如何理解协方差与反方差之差?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (12)

我很难理解协方差和反方差之间的区别。

提问于
用户回答回答于

考虑所有C#类型集的以下两个子集。第一:

{ Animal, 
  Tiger, 
  Fruit, 
  Banana }.

第二,这一套明确相关的内容:

{ IEnumerable<Animal>, 
  IEnumerable<Tiger>, 
  IEnumerable<Fruit>, 
  IEnumerable<Banana> }

因此,在我们的第一个子集中,下面是所有赋值兼容性关系:

Tiger  ⇒ Tiger
Tiger  ⇒ Animal
Animal ⇒ Animal
Banana ⇒ Banana
Banana ⇒ Fruit
Fruit  ⇒ Fruit

C#4支持某些接口的协变量赋值兼容性,在第二组中的类型对之间存在赋值兼容性关系:

IE<Tiger>  ⇒ IE<Tiger>
IE<Tiger>  ⇒ IE<Animal>
IE<Animal> ⇒ IE<Animal>
IE<Banana> ⇒ IE<Banana>
IE<Banana> ⇒ IE<Fruit>
IE<Fruit>  ⇒ IE<Fruit>

这是协方差。现在,考虑所有类型集的以下子集:

{ IComparable<Tiger>, 
  IComparable<Animal>, 
  IComparable<Fruit>, 
  IComparable<Banana> }

现在我们有了从第一组到第三组的映射。T → IC<T>

在C#4中:

IC<Tiger>  ⇒ IC<Tiger>
IC<Animal> ⇒ IC<Tiger>     Backwards!
IC<Animal> ⇒ IC<Animal>
IC<Banana> ⇒ IC<Banana>
IC<Fruit>  ⇒ IC<Banana>     Backwards!
IC<Fruit>  ⇒ IC<Fruit>

用户回答回答于

协方差

典型的例子:IEnumerable<out T>Func<out T>

您可以从IEnumerable<string>IEnumerable<object>,或Func<string>Func<object>

这是因为如果您只从API中提取值,并且它将返回特定的值(例如string),您可以将返回的值视为更一般的类型(如object)

反方差

典型的例子:IComparer<in T>Action<in T>

您可以从IComparer<object>IComparer<string>,或Action<object>Action<string>价值。

扫码关注云+社区