C# interface static method call with generics
是否有一种简单的方法来实现这一点,如果可能,在不通知对象的情况下:
1 2 3 4 5 6 7 8 9 10 11 12 13 | interface I { static string GetClassName(); } public class Helper { static void PrintClassName<T>() where T : I { Console.WriteLine(T.GetClassName()); } } |
改为尝试扩展方法:
1 2 3 4 5 6 7 8 9 10 11 12 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实现的实例。
静态方法不能有接口,因为它没有意义,它们是没有实例的实用方法,因此它们没有真正的类型。
不能继承静态方法。您的代码不会以任何方式编译,因为这样接口就不能有静态方法。
引自Littleguru:
Inheritance in .NET works only on
instance base. Static methods are
defined on the type level not on the
instance level. That is why overriding
doesn't work with static
methods/properties/events...Static methods are only held once in
memory. There is no virtual table etc.
that is created for them.If you invoke an instance method in
.NET, you always give it the current
instance. This is hidden by the .NET
runtime, but it happens. Each instance
method has as first argument a pointer
(reference) to the object that the
method is run on. This doesn't happen
with static methods (as they are
defined on type level). How should
the compiler decide to select the
method to invoke?
号
如果只是在类型名之后,则可以执行以下操作:
1 2 3 4 5 6 7 |
号
不久前我还尝试在一个接口上设置一个静态方法,现在还不知道为什么。我做了这个书签,所以它可能有帮助:
使用扩展方法与静态方法接口
在接口定义上声明
答案是一个合格的"不是真的,但有点"。可以为给定接口的所有实现者提供静态扩展方法,然后可以从属性或其他方法中的实现者调用该方法。例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | 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作为变量直接引用是无效的,您必须将实例传递到应用程序中。
可以将类名定义为特定类的属性。这是在.NET中存储元数据的首选方法。这样就可以查询给定类的属性,而不需要实例。