理解 C# 泛型接口中的協(xié)變與逆變(抗變)_第1頁
理解 C# 泛型接口中的協(xié)變與逆變(抗變)_第2頁
理解 C# 泛型接口中的協(xié)變與逆變(抗變)_第3頁
理解 C# 泛型接口中的協(xié)變與逆變(抗變)_第4頁
理解 C# 泛型接口中的協(xié)變與逆變(抗變)_第5頁
已閱讀5頁,還剩8頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、最近在看C#高級(jí)編程(第九版)這本書,看到了泛型接口這章。其中關(guān)于協(xié)變和逆變沒太理解,講得有點(diǎn)坑爹,網(wǎng)上查了許多資料,總算(感覺)弄清楚了,來這里記錄一下。一、協(xié)變和逆變是什么?先從字面上理解 協(xié)變(Covariance)、逆變(Contravariance)。co- 是英文中表示“協(xié)同”、“合作”的前綴。協(xié)變 的字面意思就是 “與變化的方向相同”。contra- 是英文中表示“相反”的前綴,逆變 的字面意思就是是 “與變化方向相反”。那么問題來了,挖掘機(jī)技術(shù)哪家強(qiáng)?這里的 變化方向 指的是什么?C# 中

2、對(duì)于對(duì)象(即對(duì)象引用),僅存在一種隱式類型轉(zhuǎn)換,即 子類型的對(duì)象引用到父類型的對(duì)象引用的轉(zhuǎn)換。這里的變化指的就是這種 子->父 的類型轉(zhuǎn)換。object o = "hello"/string (子類)類型的引用轉(zhuǎn)換為 object (父類)類型的引用協(xié)變與逆變雖然從名字上看是兩個(gè)完全相反的轉(zhuǎn)換,但其實(shí)只是“子類型引用到父類型引用”這一過程在函數(shù)中使用的 兩個(gè)不同階段 而已,接下來將詳細(xì)說明這點(diǎn)。二、使用函數(shù)的不同階段發(fā)生的類型轉(zhuǎn)換假設(shè)有一函數(shù),接收 object 類型的參數(shù),輸出 stri

3、ng 類型的返回值:string Method(object o) return "abc"那么在Main函數(shù)中我們可以這樣調(diào)用它:string s = "abc"object o = Method(s);注意,這里發(fā)生了兩次隱式類型轉(zhuǎn)換:1. 在向函數(shù)輸入時(shí),參數(shù) s 由 string 類型轉(zhuǎn)換為 object 類型2. 在函數(shù)輸出(返回)時(shí),返回值 由 string 類型轉(zhuǎn)換為 object 類型我們這里可以看作是函數(shù)簽名可發(fā)生變換(不論函數(shù)

4、的內(nèi)容,不影響結(jié)果):1. string Method(object o) 可變換為 string Method(string o)2. string Method(string o) 可變換為 object Method(string o)也就是說,在函數(shù)輸入時(shí),函數(shù)的 輸入類型 可由 object 變換為 string,父->子在函數(shù)輸出時(shí),函數(shù)的 輸出類型 可由string變換為object,子->父三、理解泛型接口中的 in、out參數(shù)沒有指定in、out

5、的情況假設(shè)有一泛型接口,并且有一個(gè)類實(shí)現(xiàn)了此接口:interface IDemo<T> T Method(T value);public class Demo : IDemo<string> /實(shí)現(xiàn)接口 IDemo<string> public string Method(string value) return value; 在Main函數(shù)中這樣寫:IDemo<string> demoStr = new Demo();IDemo<object> demoObj = demoStr;上面的這段代碼中的第二行包含了一個(gè)假設(shè):IDemo&

6、lt;string> 類型能夠隱式轉(zhuǎn)換為 IDemo<object> 類型這乍看上去就像“子類型引用轉(zhuǎn)換為父類型引用” 一樣,然而很遺憾,他們并不相同。假如可以進(jìn)行隱式類型轉(zhuǎn)換,那就意味著:string Method(string value) 能轉(zhuǎn)換為 object Method(object value)從上一節(jié)中我們知道,在函數(shù)這輸入和輸出階段,其類型可變化方向是不同的。所以在C#中,要想應(yīng)用泛型接口類型的隱式轉(zhuǎn)換,需要討論“輸入”和“輸出”兩種情況。接口僅用于輸出的情況,協(xié)變interface IDemo<out

7、 T> /僅將類型 T 用于輸出 T Method(object value);public class Demo : IDemo<string> /實(shí)現(xiàn)接口 public string Method (object value) /別忘了類型轉(zhuǎn)換! return value.ToString(); 在Main函數(shù)中這樣寫:IDemo<string> demoStr = new Demo();IDemo<object> demoObj = demoStr;可將 string Method (object value) 轉(zhuǎn)換為

8、0;object Method (object value)即可將 IDemo<string> 類型轉(zhuǎn)換為 IDemo<object> 類型。僅從泛型的類型上看,這是 “子->父” 的轉(zhuǎn)換,與第一節(jié)中提到的轉(zhuǎn)換方向相同,稱之為“協(xié)變”。接口僅用于輸入的情況,逆變同理我們可以給 T 加上 in 參數(shù):interface IDemo<in T> /僅將類型 T 用于輸入 string Method(T value);public class Demo : IDemo<ob

9、ject> /實(shí)現(xiàn)接口 public string Method (object value) return value.ToString(); 在Main函數(shù)中這樣寫:IDemo<object> demoObj = new Demo();IDemo<string> demoStr = demoObj;這里可將 string Method (object value) 轉(zhuǎn)換為 string Method (string value)即可將 IDemo<object> 類型轉(zhuǎn)換為 IDemo<string> 類型。僅從泛型的類型上看,這是 “父->子” 的轉(zhuǎn)換,與第一節(jié)中提到的轉(zhuǎn)換方向相反,稱之為“逆變”,有時(shí)也譯作“抗變”或“反變”。四、總結(jié)以上只討論了協(xié)變與逆變?cè)诜椒ㄖ械那闆r,其實(shí)在屬性中情況也相類似,不再說明。可能大家也發(fā)現(xiàn)了,所謂“協(xié)”與“逆”都是只是一種表象,其內(nèi)在本質(zhì)為同一過程?!皡f(xié)變”與“逆變”中的“協(xié)”與“逆”表示泛型接口在將類型參數(shù)僅用于輸入或輸出的情況下,其類型參數(shù)的隱式轉(zhuǎn)換

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論