C#接口静态方法调用generics

有没有一种简单的方法来实现它,如果可能的话,不需要实例化对象:

interface I { static string GetClassName(); } public class Helper { static void PrintClassName() where T : I { Console.WriteLine(T.GetClassName()); } } 

请尝试使用扩展方法:

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

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

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

您不能inheritance静态方法。 您的代码不会以任何方式编译,因为接口因此而无法使用静态方法。

引自littleguru :

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

静态方法只在内存中保存一次。 没有为它们创建的虚拟表等。

如果在.NET中调用实例方法,则始终为其提供当前实例。 这是.NET运行时隐藏的,但它发生了。 每个实例方法都将第一个参数作为运行该方法的对象的指针(引用)。 静态方法不会发生这种情况(因为它们是在类型级别定义的)。 编译器应该如何决定选择要调用的方法?

我也尝试过很久以前在界面上设置一个静态方法,不知道为什么现在。 我做了这个书签,所以也许它有帮助:

使用扩展方法与静态方法接口

如果您只是在类型名称之后,您可以这样做:

 public class Helper { static void PrintClassName() { Console.WriteLine(typeof(T).Name); } } 

在接口定义上声明static propertyeventmethod不被视为合法定义。 这是因为接口被视为契约,因此表示将由该接口的每个客户端实例实现的内容。

static声明基本上声明static成员不需要物理客户端实现来执行所需的function,这不符合接口的一般概念:提供经过validation的合同。

答案是合格的“不是真的,而是排序的”。 您可以为给定接口的所有实现者提供静态扩展方法,然后可以从属性或其他方法中的实现者调用它。 举个例子:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace InterfacesWithGenerics { class Program { static void Main(string[] args) { Helper.PrintClassName(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 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接口的类(示例),所以当我们调用我们的静态助手类传递一个Example实例时,它会对它运行静态方法。 不幸的是,将方法本身直接引用类型T作为变量是无效的,您必须将实例传递给应用程序。

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