我可以有一个既是协变又是逆变的类型吗?子类型和超级类型完全可替换/可更改?
-
25-09-2019 - |
题
我可以有一个可以协变和逆变的类型(现在忘记它的语义)吗?
例如:
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 的泛型类型有什么意义?
不隶属于 StackOverflow