繁体   English   中英

为什么不能将带有类型参数的类专门用作参数类型的协变呢?

[英]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类的类几乎没有用处,但是差异规则看起来相当广泛且广泛,我很好奇是否有更好的规则在起作用。)

TWrapperImpl<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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM