我有以下定义:
interface BaseInterface{} interface NewInterface:BaseInterface{} class NewClass:NewInterface{} class Genericclass<T> where T:BaseInterface { public string WhoIAm(T anObject) { return Testpolymorphism.CheckInterface(anObject); } } class ImplementedClass:Genericclass<NewInterface>{} class Testpolymorphism { public static string CheckInterface(BaseInterface anInterface) { return "BaseInterface"; } public static string CheckInterface(NewInterface anInterface) { return "NewInterface"; } }
然后当我打电话:
NewClass nc = new NewClass(); ImplementedClass impClass = new ImplementedClass(); Console.WriteLine("The result is " + impClass.WhoIAm(nc));
我有“结果是BaseInterface”
我期待着“结果是NewInterface”,因为nc实现了BaseClass和NewClass
获得“NewClass”的最佳方法是什么?
谢谢
解决方法
因此这样
class Genericclass<T> where T:BaseInterface { public string WhoIAm(T anObject) { return Testpolymorphism.CheckInterface(anObject); } }
将解决到需要一个BaseInterface的重载,因为这是你限制它,而不管实际上是什么类型.
C#中的泛型不像C中的模板,在C#泛型中,所有引用类型共享相同的通用代码,因此它们在编译时都类似地处理通用类型.这意味着任何编译时间都会重载使用泛型类型占位符的泛型调用,只能由泛型类型本身提供的任何约束执行,因为泛型在实际实现之前被编译.
也就是说,你的Genericclass< T>是在考虑任何使用之前进行编译(这与C做模板的方式截然不同 – 两种方法都有其优缺点).所以,如果你有一个无约束的泛型(比如说只是T),那么它被认为是重载的目的(粗略地说),但是如果你有一个约束的泛型(比如说T:BaseInterface),那么它被认为是BaseInterface超载的目的
在这种情况下你会看到类似的东西:
public static bool UberEquals<T>(T left,T right) where T : class { return left == right; }
所以你会想:如果你打电话给:
var s1 = "ello"; var s2 = "Hello"; UberEquals<string>('H' + s1,s2);
由于T是类型字符串,所以它会调用strings == overload,但它不会,因为你没有约束T,因此在编译时,它假定对象的最小公分母,并使用对象==.
另一种想法:
BaseInterface bi = new ImplementedClass(); var x = Testpolymorphism.CheckInterface(bi);
X将始终表示BaseInterface,因为重载在编译时解决,而不是在运行时动态地解析.非常类似于泛型,只要记住,通用编译是在实现之前编译的,所以它只能用于限制它的任何基类或接口,以实现重载解析.
原文地址:https://www.jb51.cc/csharp/94630.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。