代码之家  ›  专栏  ›  技术社区  ›  Toto

使用泛型的接口静态方法调用

  •  27
  • Toto  · 技术社区  · 15 年前

    是否有一种简单的方法来实现这一点,如果可能,在不通知对象的情况下:

    interface I
    {
         static  string GetClassName();
    }
    
    public class Helper
    {
    
        static void PrintClassName<T>() where T : I
        {
             Console.WriteLine(T.GetClassName());
        }
    }
    
    7 回复  |  直到 13 年前
        1
  •  24
  •   makerofthings7    13 年前

    改为尝试扩展方法:

    public interface IMyInterface
    {
         string GetClassName();
    }
    
    public static class IMyInterfaceExtensions
    {
        public static void PrintClassName<T>( this T input ) 
            where T : IMyInterface
        {
             Console.WriteLine(input.GetClassName());
        }
    }
    

    这允许您添加静态扩展/实用程序方法,但您仍然需要imyinterface实现的实例。

    静态方法不能有接口,因为它没有意义,它们是没有实例的实用方法,因此它们没有真正的类型。

        2
  •  7
  •   Dykam    15 年前

    不能继承静态方法。您的代码不会以任何方式编译,因为这样接口就不能有静态方法。

    引用自 littleguru :

    .NET中的继承仅在 实例库。静态方法是 在类型级别上定义,而不是在 实例级别。这就是为什么要凌驾于 不适用于静态 方法/属性/事件…

    静态方法只保留一次 记忆。没有虚拟表等。 这是为他们创建的。

    如果在 .NET,你总是给它电流 实例。这被.NET隐藏 运行时,但它会发生。每个实例 方法的第一个参数是指针 (引用)指向 方法正在运行。这不会发生的 用静态方法 在类型级别上定义)。 该如何 编译器决定选择 要调用的方法?

        3
  •  3
  •   Nick Clarke    15 年前

    不久前我还尝试在一个接口上设置一个静态方法,现在还不知道为什么。我做了这个书签,所以它可能有帮助:

    Interface with a static method by using extension methods

        4
  •  3
  •   Tim Cooper    13 年前

    如果只是在类型名之后,则可以执行以下操作:

    public class Helper
    {
        static void PrintClassName<T>()
        {
             Console.WriteLine(typeof(T).Name);
        }
    }
    
        5
  •  2
  •   Mike J    15 年前

    声明一个 static property , event method 接口上的定义不被视为合法定义。这是因为接口被视为契约,因此表示 由该接口的每个客户端实例实现。

    静止的 声明基本上声明 静止的 成员不需要物理客户端实现来执行所需的功能,这与接口的一般概念不符:提供经验证的合同。

        6
  •  1
  •   Wolfwyrd    15 年前

    答案是一个合格的“不是真的,但有点”。可以为给定接口的所有实现者提供静态扩展方法,然后可以从属性或其他方法中的实现者调用该方法。例如:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace InterfacesWithGenerics
    {
        class Program
        {
            static void Main(string[] args)
            {
                Helper.PrintClassName<Example>(new Example());
                Console.ReadLine();
            }
        }
    
        public class Example : I
        {
            #region I Members
    
            public string ClassName
            {
                get { return this.GetClassName(); }
            }
    
            #endregion
        }
    
        public interface I
        {
            string ClassName { get; }
        }
    
        public class Helper
        {
    
            public static void PrintClassName<T>(T input) where T : I
            {           
                Console.WriteLine( input.GetClassName()) ;
            }
        }
    
        public static class IExtensions
        {
            public static string GetClassName(this I yourInterface)
            {
                return yourInterface.GetType().ToString();
            }
        }
    }
    

    这里我们有一个接口(i),它定义了我们关心的属性,还有一个静态扩展方法(getClassName),该方法应用于它类型的所有成员,它完成了获取所需信息的繁重工作。我们有一个实现i接口的类(示例),因此当我们调用在示例实例中传递的静态助手类时,它会对其运行静态方法。不幸的是,将方法本身中的类型T作为变量直接引用是无效的,您必须将实例传递到应用程序中。

        7
  •  0
  •   codymanix    15 年前

    可以将类名定义为特定类的属性。这是在.NET中存储元数据的首选方法。这样就可以查询给定类的属性,而不需要实例。