好的,我在stackoverflow上阅读了有关该主题的内容,观看了&this,但是对于co / contra-variance还是有些困惑。
从这里
协方差允许在原始类型仅用于“输出”位置(例如,作为返回值)的API中替换“较大”(较不具体)的类型。协变性允许在原始类型仅用于“输入”位置的API中替换“较小”(更具体)的类型。
我知道这与类型安全有关。
关于这in/out件事。我可以说我in何时需要写它,out何时需要它只读。和in装置,禁忌方差,out协方。但是根据上面的解释…
in/out
in
out
与此
例如,List<Banana>不能将a视为a,List<Fruit>因为 list.Add(new Apple())它对List有效,但对无效List<Banana>。
List<Banana>
List<Fruit>
list.Add(new Apple())
所以不应该,如果我要使用in/要写入该对象,则它必须更大,更通用。
我知道有人问过这个问题,但仍然很困惑。
C#4.0中的协方差和协方差都涉及使用派生类而不是基类的能力。in / out关键字是编译器提示,用于指示是否将类型参数用于输入和输出。
C#4.0中的协方差由out关键字辅助,这意味着使用outtype参数的派生类的泛型类型是可以的。因此
IEnumerable<Fruit> fruit = new List<Apple>();
由于Apple是Fruit,List<Apple>可以安全地用作IEnumerable<Fruit>
Apple
Fruit
List<Apple>
IEnumerable<Fruit>
矛盾是in关键字,它表示输入类型,通常在委托中。原理是相同的,这意味着委托可以接受更多派生类。
public delegate void Func<in T>(T param);
这意味着如果我们有一个Func<Fruit>,可以将其转换为Func<Apple>。
Func<Fruit>
Func<Apple>
Func<Fruit> fruitFunc = (fruit)=>{}; Func<Apple> appleFunc = fruitFunc;
因为即使原理相同,也可以安全地从派生类型转换为基类,但在输入类型上使用时,我们可以安全地将较少派生类型(Func<Fruit>)强制转换为更多派生类型(Func<Apple>),这很有意义,因为任何需要Fruit,也可以服用Apple。