圖文詳解C#中的協(xié)變與逆變
前言
這篇文章簡(jiǎn)單說(shuō)說(shuō)C#中的協(xié)變和逆變。
在C#編程中,由于存在類型之間的強(qiáng)制轉(zhuǎn)換,很容易會(huì)出現(xiàn)所謂的類型可變性說(shuō)法,存在協(xié)變、逆變、不變?nèi)N。
就比如前一篇文章介紹的泛型概念,如果創(chuàng)建了泛型類型的實(shí)例,編譯器會(huì)接受泛型類型聲明以及類型參數(shù)來(lái)創(chuàng)建構(gòu)造類型。但是在日常使用過(guò)程中,我們可能會(huì)將派生類型分配給基類型的變量,有時(shí)候會(huì)出現(xiàn)錯(cuò)誤。
這里就存在一個(gè)賦值兼容性問(wèn)題。
每一個(gè)變量都有一種類型,可以將派生類對(duì)象的實(shí)例賦值給基類變量(好比之前子類聲明的變量可以賦值給父類聲明的變量一樣)。
如下所示:
class People { public int Age = 27; } class AhuiPeople : People { }
People ahui = new People(); People people = new AhuiPeople(); Console.WriteLine("Age:"+people.Age); Console.ReadKey();
協(xié)變和逆變
我們按照同樣的邏輯,在泛型委托中進(jìn)行這種強(qiáng)類型的轉(zhuǎn)換,會(huì)發(fā)現(xiàn)即使基類和派生類之間可以進(jìn)行正常的轉(zhuǎn)換,但是委托之間不能進(jìn)行轉(zhuǎn)換會(huì)出現(xiàn)異常錯(cuò)誤提示。
具體如下代碼所示:
delegate T AgeDelegate<T>(); static AhuiPeople GetAge() { return new AhuiPeople(); }
在轉(zhuǎn)換過(guò)程中,委托的具體用法,但是這樣子編譯器提示錯(cuò)誤。
AgeDelegate<AhuiPeople> ahui = GetAge; AgeDelegate<People> people = ahui;
錯(cuò)誤提示
這就是上面解釋的那樣子,基類和派生類之間可以進(jìn)行轉(zhuǎn)換但是委托之間未存在關(guān)聯(lián),無(wú)法進(jìn)行強(qiáng)制類型的轉(zhuǎn)換。
那么想解決這個(gè)問(wèn)題就引入了協(xié)變來(lái)解決。
如果派生類只是用于輸出值,那么這種結(jié)構(gòu)化的委托有效性之間的常數(shù)關(guān)系叫做協(xié)變,可通過(guò)主動(dòng)告知編譯器我們的期望,使用Out關(guān)鍵字標(biāo)記委托聲明中的類型參數(shù)。
delegate T AgeDelegate<out T>();
修改成這樣子后,上面錯(cuò)誤演示的代碼編譯器就可以正常編譯通過(guò)了。
上面簡(jiǎn)單介紹了協(xié)變,那么接下來(lái)我們來(lái)看逆變是什么。
其實(shí)逆變就是在委托中既要聲明委托類型,也要在委托方法中有實(shí)參。
這種在期望傳入基類時(shí)允許傳入派生對(duì)象的特性叫做逆變。 逆變使用關(guān)鍵字in來(lái)標(biāo)記。
具體如下代碼所示:
delegate void AgeDelegate<in T>(T p); static void GetAge(People p) { Console.WriteLine(p.Age); }
AgeDelegate<People> ahui = GetAge; AgeDelegate<AhuiPeople> people = ahui; people(new AhuiPeople()); Console.WriteLine(); Console.ReadKey();
輸出結(jié)果
既然協(xié)變和逆變可以使用在委托上,那么接口上也可以使用,此時(shí)也需要使用out和in關(guān)鍵字。
總結(jié)
到此這篇關(guān)于C#中協(xié)變與逆變的文章就介紹到這了,更多相關(guān)C#協(xié)變與逆變內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺談static a[n*m]={0};中static的作用
下面小編就為大家?guī)?lái)一篇淺談static a[n*m]={0};中static的作用。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-03-03C#用遞歸算法實(shí)現(xiàn):一列數(shù)的規(guī)則如下: 1、1、2、3、5、8、13、21、34,求第30位數(shù)是多少
本文主要介紹三種方法,解決面試中常見(jiàn)的問(wèn)題,求第30位數(shù)是多少的問(wèn)題,希望能給大家一個(gè)參考。2016-06-06C#實(shí)現(xiàn)發(fā)送手機(jī)驗(yàn)證碼功能
之前基于c#實(shí)現(xiàn)手機(jī)發(fā)送驗(yàn)證碼功能很復(fù)雜,真正做起來(lái)也就那回事,不過(guò)就是一個(gè)post請(qǐng)求就可以實(shí)現(xiàn)的東西,今天小編把思路分享到腳本之家平臺(tái),供大家參考下2017-06-06