逆变,协变
定义:
逆变 :指能够使用比原始指定的派生类型的 派生程度更小(不太具体的)的类型。
协变 :能够使用比原始指定的派生类型的 派生程度更大(更具体的)的类型。
看了上面一脸懵逼,下面会解释
示例
这是用来讲解例子的两个类
public class Father
{
public string Name { get; set; }
}
public class Son : Father
{
public int Age { get; set; }
}
协变 out
Father f = new Son();
先来看这一句 这是我们熟悉的, 因为Son继承自Father, 所以编译可以通过。
我们可以认为:
Father(基类) 相对于 Son(子类) 是派生程度更大(更具体的)的类型。
Son(子类) 相对于 Father(基类) 派生程度更小(不太具体的)的类型
再来看这一句
List<Son> sons = new List<Son>();
List<Father> fathers = sons; // error
为什么为编译失败呢,因为编译器知道 Father 和 Son 是继承关系,但是不知道List< Father > 和 List< Son > 是什么关系。
List<Son> sons = new List<Son>();
IEnumerable<Father> fathers = sons; // success
这是协变,可以允许使用比原指定类型派生程度更大(更具体的)的类型。
逆变 in
逆变也称为不正常的变化
比如Father转为Son,这肯定不行。
Action <Father> func1 = new Action<Father>(a => { Console.WriteLine($"{a.Name}"); });
func1是输出Father的Name,那既然Father能输出Name为什么Son不能输出Name呢? 如下就可以,因为Action
Action <Father> func1 = new Action<Father>(a => { Console.WriteLine($"{a.Name}"); });
Action <Son> func2 = func1;
这是逆变 可以使用比原指定类型派生程度更小(不太具体的)的类型。