一篇文章看懂C#中的協(xié)變、逆變
1. 基本概念
官方:協(xié)變和逆變都是術(shù)語(yǔ),前者指能夠使用比原始指定的派生類型的派生程度更大(更具體的)的類型,后者指能夠使用比原始指定的派生類型的派生程度更小(不太具體的)的類型。[MSDN]
公式:
協(xié)變:IFoo<父類> = IFoo<子類>;
逆變:IBar<子類> = IBar<父類>;
暫時(shí)不理解沒(méi)關(guān)系,您接著往下看。
2. 協(xié)變(Covariance)
1) out關(guān)鍵字
對(duì)于泛型類型參數(shù),out 關(guān)鍵字可指定類型參數(shù)是協(xié)變的。 可以在泛型接口和委托中使用 out 關(guān)鍵字。[MSDN]
2) 魯迅:一張圖勝過(guò)千言萬(wàn)語(yǔ)(圖小看不清,單機(jī)鼠標(biāo)右鍵 -> 在新標(biāo)簽頁(yè)中打開圖片)
備注:泛型委托的協(xié)變?cè)硪彩且粯拥摹?/p>
3) 什么是協(xié)變?
協(xié)變就是對(duì)具體成員的輸出參數(shù)進(jìn)行一次類型轉(zhuǎn)換,且類型轉(zhuǎn)換的準(zhǔn)則是 “里氏替換原則”。
3. 逆變(Contravariance)
1) in關(guān)鍵字
對(duì)于泛型類型參數(shù),in 關(guān)鍵字可指定類型參數(shù)是逆變的。 可以在泛型接口和委托中使用 in 關(guān)鍵字。[MSDN]
2) 魯迅:一張圖勝過(guò)千言萬(wàn)語(yǔ)(圖小看不清,單機(jī)鼠標(biāo)右鍵 -> 在新標(biāo)簽頁(yè)中打開圖片)
備注:泛型委托的逆變?cè)硪彩且粯拥摹?/p>
3) 什么是逆變?
逆變就是對(duì)具體成員的輸入?yún)?shù)進(jìn)行一次類型轉(zhuǎn)換,且類型轉(zhuǎn)換的準(zhǔn)則是 “里氏替換原則”。
4. 自問(wèn)自答
1)協(xié)變、逆變 為什么只能針對(duì)泛型接口或者委托?而不能針對(duì)泛型類?
因?yàn)樗鼈兌贾荒芏x方法成員(接口不能定義字段),而方法成員在創(chuàng)建對(duì)象的時(shí)候是不涉及到對(duì)象內(nèi)存分配的,所以它們是類型(內(nèi)存)安全的。
為什么不針對(duì)泛型?因?yàn)榉盒皖愂悄0孱?,而類成員是包含字段的,不同類型的字段是影響對(duì)象內(nèi)存分配的,沒(méi)有派生關(guān)系的類型它們是不兼容的,也是內(nèi)存不安全的。
2)協(xié)變、逆變 為什么是類型安全的?
本質(zhì)上是里氏替換原則,由里氏替換原則可知:派生程度小的是派生程度大的子集,所以子類替換父類的位置整個(gè)程序功能都不會(huì)發(fā)生改變。
3)官方對(duì) 協(xié)變、逆變 的定義現(xiàn)在是否能看懂?
上面看懂了,官方定義肯定也是沒(méi)問(wèn)題的。派生程度小可以理解為基類,派生程度大可以理解為子類或派生類,至于為什么用程度這個(gè)詞,是因?yàn)槔^承鏈的深度是沒(méi)限制的。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
C#實(shí)現(xiàn)對(duì)字符串進(jìn)行大小寫切換的方法
這篇文章主要介紹了C#實(shí)現(xiàn)對(duì)字符串進(jìn)行大小寫切換的方法,涉及C#操作字符串的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03
C#byte數(shù)組與Image的相互轉(zhuǎn)換實(shí)例代碼
這篇文章主要介紹了C#byte數(shù)組與Image的相互轉(zhuǎn)換實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2017-04-04
C# Ado.net實(shí)現(xiàn)讀取SQLServer數(shù)據(jù)庫(kù)存儲(chǔ)過(guò)程列表及參數(shù)信息示例
Unity實(shí)現(xiàn)簡(jiǎn)單虛擬搖桿
在C#中使用OpenCV(使用OpenCVSharp)的實(shí)現(xiàn)

