C# 協變 逆變
阿新 • • 發佈:2020-12-17
逆變,協變
定義:
逆變 :指能夠使用比原始指定的派生型別的 派生程度更小(不太具體的)的型別。
協變 :能夠使用比原始指定的派生型別的 派生程度更大(更具體的)的型別。
看了上面一臉懵逼,下面會解釋
示例
這是用來講解例子的兩個類
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;
這是逆變 可以使用比原指定型別派生程度更小(不太具體的)的型別。