一尘不染

仍然对协方差和矛盾和输入/输出感到困惑

c#

好的,我在stackoverflow上阅读了有关该主题的内容,观看this,但是对于co / contra-variance还是有些困惑。

这里

协方差允许在原始类型仅用于“输出”位置(例如,作为返回值)的API中替换“较大”(较不具体)的类型。协变性允许在原始类型仅用于“输入”位置的API中替换“较小”(更具体)的类型。

我知道这与类型安全有关。

关于这in/out件事。我可以说我in何时需要写它,out何时需要它只读。和in装置,禁忌方差,out协方。但是根据上面的解释…

例如,List<Banana>不能将a视为a,List<Fruit>因为 list.Add(new Apple())它对List有效,但对无效List<Banana>

所以不应该,如果我要使用in/要写入该对象,则它必须更大,更通用。

我知道有人问过这个问题,但仍然很困惑。


阅读 220

收藏
2020-05-19

共1个答案

一尘不染

C#4.0中的协方差和协方差都涉及使用派生类而不是基类的能力。in / out关键字是编译器提示,用于指示是否将类型参数用于输入和输出。

协方差

C#4.0中的协方差由out关键字辅助,这意味着使用outtype参数的派生类的泛型类型是可以的。因此

IEnumerable<Fruit> fruit = new List<Apple>();

由于AppleFruitList<Apple>可以安全地用作IEnumerable<Fruit>

逆差

矛盾是in关键字,它表示输入类型,通常在委托中。原理是相同的,这意味着委托可以接受更多派生类。

public delegate void Func<in T>(T param);

这意味着如果我们有一个Func<Fruit>,可以将其转换为Func<Apple>

Func<Fruit> fruitFunc = (fruit)=>{};
Func<Apple> appleFunc = fruitFunc;

如果它们基本上是相同的东西,为什么将它们称为协/逆方差?

因为即使原理相同,也可以安全地从派生类型转换为基类,但在输入类型上使用时,我们可以安全地将较少派生类型(Func<Fruit>)强制转换为更多派生类型(Func<Apple>),这很有意义,因为任何需要Fruit,也可以服用Apple

2020-05-19