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
property
, event
或method
不被视为合法定义。 这是因为接口被视为契约,因此表示将由该接口的每个客户端实例实现的内容。
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中存储元数据的首选方法。 这样,您可以查询给定类的属性,而不需要实例。