本篇文章給大家分享的是有關(guān)c#中協(xié)變與逆變的定義是什么,小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說(shuō),跟著小編一起來(lái)看看吧。
我們一直強(qiáng)調(diào)成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)對(duì)于企業(yè)的重要性,如果您也覺(jué)得重要,那么就需要我們慎重對(duì)待,選擇一個(gè)安全靠譜的網(wǎng)站建設(shè)公司,企業(yè)網(wǎng)站我們建議是要么不做,要么就做好,讓網(wǎng)站能真正成為企業(yè)發(fā)展過(guò)程中的有力推手。專業(yè)網(wǎng)絡(luò)公司不一定是大公司,創(chuàng)新互聯(lián)作為專業(yè)的網(wǎng)絡(luò)公司選擇我們就是放心。基本概念
協(xié)變:能夠使用比原始指定的派生類型的派生程度更大(更具體)的類型。例如 IFoo<父類> = IFoo<子類>
逆變:能夠使用比原始指定的派生類型的派生程度更新(更抽象)的類型。例如 IBar<子類> = IBar<父類>
關(guān)鍵字out和in
協(xié)變和逆變?cè)诜盒蛥?shù)中的表現(xiàn)方式,out關(guān)鍵字表示協(xié)變,in關(guān)鍵字表示逆變。二者只能在泛型接口或者委托中使用。
理解協(xié)變和逆變
看完上面的定義是不是一臉懵逼~~~??床欢蛯?duì)了,且定義語(yǔ)句的歧義性很大。讓我們大腦趕緊清空下?。∈紫扔涀∫稽c(diǎn)明確的概念,類的多態(tài)展示一定是通過(guò)基類來(lái)表示,派生的具體類都是可轉(zhuǎn)化為基類,而不能走相反的流程。
下面我們用代碼直觀的表現(xiàn)下協(xié)變和逆變。
public class Animal { public void Eat() { } } public class Dog : Animal { public void Run() { } }
這是一段很簡(jiǎn)單的子類和父類的關(guān)系,我們進(jìn)行一下簡(jiǎn)單的轉(zhuǎn)化,應(yīng)該很好理解,Dog子類可以用Animal父類展示,反過(guò)來(lái)則不可以,會(huì)編譯錯(cuò)誤。
Dog dog = new Dog(); Animal animal = dog; //error 編譯錯(cuò)誤 //Dog dog2 = animal;
那么我們做一點(diǎn)變化。
Listdogs = new List (); //error 編譯錯(cuò)誤 //List animals_2 = dogs; IEnumerable dogs_2 = dogs; IEnumerable animals = dogs_2;
感覺(jué)到一點(diǎn)問(wèn)題沒(méi)?Dog子類可以用Animal父類展示,使用List泛型就不可以了,但是IEnumerable泛型又可以。List<>和IEnumerable<>有什么不同?我們看下二者的定義即可發(fā)現(xiàn)端倪。
//IList定義 public interface IList<[NullableAttribute(2)] T> : ICollection, IEnumerable , IEnumerable {} //和IEnumerable定義 public interface IEnumerable<[NullableAttribute(2)] out T> : IEnumerable {}
區(qū)別就在于 IEnumerable的泛型參數(shù)用了out協(xié)變標(biāo)注,所以可以做正確的轉(zhuǎn)換。 這里也可以理解出什么時(shí)候需要使用in、out關(guān)鍵字:當(dāng)你設(shè)計(jì)帶有泛型的基類且泛型類型可能存在擴(kuò)展時(shí),則需要考慮使用in或者out關(guān)鍵字修飾。
我們?cè)倏纯垂俜降腁ction<>和Func<>類對(duì)協(xié)變和逆變的使用,先看定義:
public delegate void Action<[NullableAttribute(2)] in T>(T obj); public delegate TResult Func<[NullableAttribute(2)] in T, [NullableAttribute(2)] out TResult>(T arg);
Action的泛型類型是入?yún)?,用in表示逆變,F(xiàn)unc的第二個(gè)泛型類型TResult是出參,用out表示協(xié)變。
那么這樣看起來(lái)對(duì)in、out關(guān)鍵字的認(rèn)識(shí)就很簡(jiǎn)單明了了。看看轉(zhuǎn)換示例:
Actionaction_dog = d => d.Run(); Action action_animal = a => a.Eat(); //error 編譯錯(cuò)誤。in //Action action_animal_2 = action_dog; //Action泛型多態(tài)化 Action action_dog_2 = action_animal; Func func_dog = a => { return new Dog(); }; Func func_animal = a => { return new Animal(); }; //Func泛型多態(tài)化 Func func_animal_2 = func_dog; //error 編譯錯(cuò)誤。out //Func func_dog_2 = func_animal;
注意注釋編譯錯(cuò)誤的語(yǔ)句,符合上面我們轉(zhuǎn)換的規(guī)則。對(duì)于入?yún)?,擴(kuò)展類可以替代基類參數(shù)輸入,用in修飾;對(duì)于出參,擴(kuò)展類可以替代基類返回輸出,用out修飾。相反則都不可以。
最后簡(jiǎn)單總結(jié)下:
什么是協(xié)變/逆變?不要去想官方定義!?。。≈灰涀ut是協(xié)變,in是逆變即可。
為什么需要使用協(xié)變-out、逆變-in。在泛型或委托中,如果不使用協(xié)變/逆變,那么泛型類型一個(gè)精確的、固定的某一類型。而使用協(xié)變/逆變的話,則泛型類型可以實(shí)現(xiàn)多態(tài)化。但必須區(qū)分入?yún)⑹褂胕n,出參使用out。
以上就是c#中協(xié)變與逆變的定義是什么,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。