我可以有一个既是协变又是逆变的类型吗?子类型和超级类型完全可替换/可更改?

StackOverflow https://stackoverflow.com/questions/2809932

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

例如:

public interface Foo<in out T>
{
    void DoFooWith(T arg);
}

请访问 Eric Lippert 的博客,了解 C# 4.0 中差异的主要内容,因为几乎没有其他地方涵盖了该主题的足够基础。


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

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

但与此同时,任何简短的、顿悟的答案都是受欢迎的。

有帮助吗?

解决方案

不,你不能那样做。

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

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

  • “in T”(大致)意思是“T 仅出现在输入位置”。
  • “out T”(大致)意思是“T 仅出现在输出位置”。

因此“in out T”意味着......什么?正如我们已经看到的,它只能意味着“T 根本没有出现在任何方法或属性中”。 在 T 中创建一个从不使用 T 的泛型类型有什么意义?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top