gpt4 book ai didi

c# - 为什么这个泛型函数不调用被覆盖的函数

转载 作者:太空宇宙 更新时间:2023-11-03 10:48:22 25 4
gpt4 key购买 nike

如果我有一个基类

class Foo : IClonable {

public object virtual Clone(){ return new Foo(); }
}

并且一个子类错误地用 new 而不是 override 覆盖克隆。这是我试图解决的第三方库中错误的简化。

class Bar : Foo {

public new Clone() { return new Bar(); }
}

然后我有两个方法

public static T Bang(T source)
where T : Foo
{
return (T) source.Clone();
}

public static Bar Bang(Bar source)
{
return (Bar) source.Clone();
}

现在,如果我用 Bar 的实例调用第一个,我会返回一个 Foo。如果我调用第二个,我会返回 Bar

我很好奇为什么通用版本没有获得 Clone()new 版本,而是继承的版本。

是不是类型T在满足约束后被删除,然后它就使用基类来表现?

最佳答案

Is it that the type T is erased after the constraints are met and then it just behaves using the base class?

这取决于您所说的“T 类型被删除”是什么意思。它不像在 Java 中那样被删除——类型参数在执行时可用,所以如果你写:

Console.WriteLine(typeof(T));

这将打印 Bar

但是,编译器在编译您的第一个 Bang 方法时需要确定调用哪个方法是该值是 Foo 类型还是某个子类型。它必须基于此生成 IL 调用一个方法。它不像编译器为每个不同的T生成一个新的Bang方法,使用实际类型T来执行方法解析等。

换句话说,就编译器而言,你的方法等同于:

public static T Bang<T>(Foo source)
where T : Foo
{
return (T) source.Clone();
}

请注意参数类型从 T 更改为 Foo,因为这是编译器必须继续处理的所有信息。

(我假设您了解就编译器和 CLR 而言,您的两个 Clone 方法大多不相关;它们碰巧具有相同的名称,但一个不会覆盖另一个是多态的。)

关于c# - 为什么这个泛型函数不调用被覆盖的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22537736/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com