我可以有一个既有协变性又有逆变性的类型,即完全可替换的子类型和超级类型?

Wat*_* v2 6 covariance contravariance variance c#-4.0

我可以有一个类型(现在忘记它的语义),它可以是协变的还是逆变的?

例如:

public interface Foo<in out T>
{
    void DoFooWith(T arg);
}
Run Code Online (Sandbox Code Playgroud)

关于Eric Lippert的博客,了解C#4.0中的差异肉和土豆,因为除此之外几乎没有什么能够涵盖这个主题的充分理由.


无论如何我试了一下,不仅不允许这样做,而且它告诉我,我错过了重点.我需要理解只读,只写和方差之间的联系.

我想我还有更多的阅读要做.

但同时,欢迎任何短暂的,顿悟的诱导答案.

Eri*_*ert 10

不,你做不到.

假设这是合法的.你做了一个IFoo<Giraffe>.由于IFoo在T中是协变的,因此您可以通过类型安全引用转换将其转换为IFoo<object>.由于它是逆变的,你可以将其转换为IFoo<Banana>.有什么可能的语义IFoo<T>,以便能够通过引用转换将长颈鹿的IFoo转换为香蕉的IFoo是有意义的吗?除了作为参考类型之外,长颈鹿和香蕉没有任何共同之处.你不可能有一个IFoo<Banana>返回香蕉的方法,因为它实际上可能是一个实现IFoo<Giraffe>; 实施的作者如何知道分发香蕉?IFoo<Banana>出于同样的原因,你不可能有一个香蕉的方法; IFoo<Giraffe>期待你把他交给长颈鹿的实施者.

这是另一种看待它的方式:

  • "在T中"意味着(大致)"T仅出现在输入位置".
  • "out T"表示(粗略地)"T仅出现在输出位置".

因此"in out T"意味着......什么?正如我们已经看到的,它只能意味着"T在任何方法或财产中根本不会出现." 在T中制作通用类型的重点是什么,你从不使用T?

  • 实际上,不使用泛型类型参数的泛型可能非常有用。所谓的“幻像类型”使代码能够以静态禁止错误操作的方式编写。规范示例可能是一个 `File&lt;T&gt;` 类型,其中类型 `T` 编码文件是否允许读取、写入或两者兼而有之,即使类的内部结构从不引用 `T`。 (4认同)
  • @kvb:与简单地创建基类File和派生类"WritableFile","ReadableFile"和"ReadableAndWritableFile"有什么不同?为什么在普通类型系统中捕获某些东西时可以简单地捕获它? (2认同)
  • 好吧,因为 .NET 不支持多重继承,所以从 ReadableFile 和 WriteableFile 派生 ReadableAndWriteableFile 是不可能的。但是,例如,您希望能够在方法需要 ReadableFile 的任何地方传入 ReadableAndWriteableFile。 (2认同)