C# 协变 逆变

逆变,协变

定义:

逆变 :指能够使用比原始指定的派生类型的 派生程度更小(不太具体的)的类型。

协变 :能够使用比原始指定的派生类型的 派生程度更大(更具体的)的类型。

看了上面一脸懵逼,下面会解释

示例

这是用来讲解例子的两个类

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;

这是逆变 可以使用比原指定类型派生程度更小(不太具体的)的类型。

C# 协变 逆变

上一篇:c# FFmpeg操作视频时文件路径或文件名中有空格的处理--FFmpeg知识点备忘之一


下一篇:关键字extern用法——C#