加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

C#中泛型类的调用不能工作

发布时间:2020-12-15 06:47:24 所属栏目:百科 来源:网络整理
导读:在以下情况下,多态性无法正常工作 我有以下定义: interface BaseInterface{}interface NewInterface:BaseInterface{}class NewClass:NewInterface{}class GenericClassT where T:BaseInterface{ public string WhoIAm(T anObject) { return TestPolymorphis
在以下情况下,多态性无法正常工作
我有以下定义:
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,因为重载在编译时解决,而不是在运行时动态地解析.非常类似于泛型,只要记住,通用编译是在实现之前编译的,所以它只能用于限制它的任何基类或接口,以实现重载解析.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读