[英]Why can't a class with a type parameter used exclusively as an argument type be covariant on it?
我发现的最常见的示例解释了为什么不能协变地使用反有效类型参数涉及构建一些派生类型的读写包装器,将其转换为基本类型的包装器,注入另一个派生类型, 然后再进行阅读那个包装的价值 ; 遵循以下内容:
class Base { public int base_property; }
class Derived : Base { public int derived_property; }
class OtherDerived : Base { public string other_derived_property; }
interface Wrapper<out T> {
void put(T v);
T pull();
}
Wrapper<Derived> derived_wrapper = new WrapperImpl<Derived>();
Wrapper<Base> cast_wrapper = (Wrapper<Base>)derived_wrapper;
cast_wrapper.put(new OtherDerived());
Derived wrapped = derived_wrapper.pull(); // Surprise! This is an OtherDerived.
我能理解为什么这是无效的。 但是,如果Wrapper
没有pull
,并且包装的属性具有私有吸气剂怎么办? (Wrapper<Base>)derived_wrapper
似乎消失了,我找不到替换它的问题。
更具体地说,我不知道以任何方式将功能取决于通用类型的最终具体类型。 毫不奇怪,断言如下类型是没有用的:
class WrapperImpl<T> : Wrapper<T> where T : Base {
public void put(T v) {
if(typeof(T).Equals(Derived)) {
Console.WriteLine(v.derived_property); // Type `T' does not contain a
// definition for `derived_property'...
}
}
}
这使我相信,这些方法中的功能只能利用T
类型所约束的属性。 即使包裹属性是OtherDerived
这里原来WrapperImpl
预期Derived
(正投)之前,没有任何方法可以想到的是包裹财产有derived_property
因为Base
是最具体的T
是保证。
我是否在这里缺少某些东西,或者这可能是编译器的一个局限性,使其无法即时具体化T
?
(我猜想像Wrapper
类的类几乎没有用处,但是差异规则看起来相当广泛且广泛,我很好奇是否有更好的规则在起作用。)
该T
在WrapperImpl<T>
可以对任何亚型约束Base
,而不仅仅是Base
本身。 如果仅将T : Base
更改为T : Derived
,则put
功能应能够安全地访问v.derived_property
。
这是麻烦的来源,当一个OtherDerived
传递给put
后的(Wrapper<Base>)derived_wrapper
铸造,在试图访问不存在derived_property
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.