最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解c# 協(xié)變和逆變

 更新時間:2020年11月27日 16:14:35   作者:gt1987  
這篇文章主要介紹了c# 協(xié)變和逆變的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)c#,感興趣的朋友可以了解下

基本概念

協(xié)變:能夠使用比原始指定的派生類型的派生程度更大(更具體)的類型。例如 IFoo<父類> = IFoo<子類>
逆變:能夠使用比原始指定的派生類型的派生程度更新(更抽象)的類型。例如 IBar<子類> = IBar<父類>

關(guān)鍵字out和in

協(xié)變和逆變在泛型參數(shù)中的表現(xiàn)方式,out關(guān)鍵字表示協(xié)變,in關(guān)鍵字表示逆變。二者只能在泛型接口或者委托中使用。

理解協(xié)變和逆變

看完上面的定義是不是一臉懵逼~~~。看不懂就對了,且定義語句的歧義性很大。讓我們大腦趕緊清空下??!首先記住一點明確的概念,類的多態(tài)展示一定是通過基類來表示,派生的具體類都是可轉(zhuǎn)化為基類,而不能走相反的流程。
下面我們用代碼直觀的表現(xiàn)下協(xié)變和逆變。

public class Animal
{
  public void Eat()
  { }
}

public class Dog : Animal
{
  public void Run()
  {
  }
}

這是一段很簡單的子類和父類的關(guān)系,我們進行一下簡單的轉(zhuǎn)化,應(yīng)該很好理解,Dog子類可以用Animal父類展示,反過來則不可以,會編譯錯誤。

    Dog dog = new Dog();
    Animal animal = dog;

    //error 編譯錯誤
    //Dog dog2 = animal;

那么我們做一點變化。

    List<Dog> dogs = new List<Dog>();
    //error 編譯錯誤
    //List<Animal> animals_2 = dogs;

    IEnumerable<Dog> dogs_2 = dogs;
    IEnumerable<Animal> animals = dogs_2;

感覺到一點問題沒?Dog子類可以用Animal父類展示,使用List泛型就不可以了,但是IEnumerable泛型又可以。List<>和IEnumerable<>有什么不同?我們看下二者的定義即可發(fā)現(xiàn)端倪。

//IList定義
public interface IList<[NullableAttribute(2)] T> : ICollection<T>, IEnumerable<T>, IEnumerable
{}

//和IEnumerable定義
public interface IEnumerable<[NullableAttribute(2)] out T> : IEnumerable
{}

區(qū)別就在于 IEnumerable的泛型參數(shù)用了out協(xié)變標注,所以可以做正確的轉(zhuǎn)換。 這里也可以理解出什么時候需要使用in、out關(guān)鍵字:當你設(shè)計帶有泛型的基類且泛型類型可能存在擴展時,則需要考慮使用in或者out關(guān)鍵字修飾。
我們再看看官方的Action<>和Func<>類對協(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的第二個泛型類型TResult是出參,用out表示協(xié)變。
那么這樣看起來對in、out關(guān)鍵字的認識就很簡單明了了??纯崔D(zhuǎn)換示例:

    Action<Dog> action_dog = d => d.Run();
    Action<Animal> action_animal = a => a.Eat();

    //error 編譯錯誤。in
    //Action<Animal> action_animal_2 = action_dog;
		//Action泛型多態(tài)化
    Action<Dog> action_dog_2 = action_animal;

    Func<int, Dog> func_dog = a => { return new Dog(); };
    Func<int, Animal> func_animal = a => { return new Animal(); };

		//Func泛型多態(tài)化
    Func<int, Animal> func_animal_2 = func_dog;
    //error 編譯錯誤。out
    //Func<int, Dog> func_dog_2 = func_animal;

注意注釋編譯錯誤的語句,符合上面我們轉(zhuǎn)換的規(guī)則。對于入?yún)ⅲ瑪U展類可以替代基類參數(shù)輸入,用in修飾;對于出參,擴展類可以替代基類返回輸出,用out修飾。相反則都不可以。

最后簡單總結(jié)下:

  • 什么是協(xié)變/逆變?不要去想官方定義?。。?!只要記住out是協(xié)變,in是逆變即可。
  • 為什么需要使用協(xié)變-out、逆變-in。在泛型或委托中,如果不使用協(xié)變/逆變,那么泛型類型一個精確的、固定的某一類型。而使用協(xié)變/逆變的話,則泛型類型可以實現(xiàn)多態(tài)化。但必須區(qū)分入?yún)⑹褂胕n,出參使用out。

以上就是詳解c# 協(xié)變和逆變的詳細內(nèi)容,更多關(guān)于c# 協(xié)變和逆變的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解C#如何使用重載方法實現(xiàn)不同類型數(shù)據(jù)的計算

    詳解C#如何使用重載方法實現(xiàn)不同類型數(shù)據(jù)的計算

    這篇文章主要為大家詳細介紹了C#如何使用重載方法實現(xiàn)不同類型數(shù)據(jù)的計算,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-02-02
  • 比較2個datatable內(nèi)容是否相同的方法

    比較2個datatable內(nèi)容是否相同的方法

    這篇文章主要介紹了比較2個datatable內(nèi)容是否相同的方法,大家參考使用吧
    2014-01-01
  • C#-WinForm跨線程修改UI界面的示例

    C#-WinForm跨線程修改UI界面的示例

    這篇文章主要介紹了C#-WinForm跨線程修改UI界面的示例,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下
    2021-01-01
  • C#?二進制序列化和反序列化的具體實現(xiàn)

    C#?二進制序列化和反序列化的具體實現(xiàn)

    本文主要介紹了C#?二進制序列化和反序列化的具體實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • C#創(chuàng)建、讀取和修改Excel的方法

    C#創(chuàng)建、讀取和修改Excel的方法

    這篇文章主要介紹了C#創(chuàng)建、讀取和修改Excel的方法,涉及C#使用Jet OLE DB操作Excel的技巧,非常具有實用價值,需要的朋友可以參考下
    2015-04-04
  • C#實現(xiàn)Winform版計算器

    C#實現(xiàn)Winform版計算器

    這篇文章主要為大家詳細介紹了C#實現(xiàn)Winform版計算器,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-05-05
  • C#溫故而知新系列教程之閉包

    C#溫故而知新系列教程之閉包

    閉包是將一些執(zhí)行語句的封裝,可以將封裝的結(jié)果像對象一樣傳遞,在傳遞時,這個封裝依然能夠訪問到原上下文。下面這篇文章主要給大家介紹了關(guān)于C#中閉包的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2018-05-05
  • WPF實現(xiàn)上下滾動字幕效果

    WPF實現(xiàn)上下滾動字幕效果

    這篇文章主要為大家詳細介紹了WPF實現(xiàn)上下滾動字幕效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • Unity實現(xiàn)虛擬搖桿效果

    Unity實現(xiàn)虛擬搖桿效果

    這篇文章主要為大家詳細介紹了Unity實現(xiàn)虛擬搖桿效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • C#使用for循環(huán)移除HTML標記

    C#使用for循環(huán)移除HTML標記

    大家在項目開發(fā)階段移除文字中的html標記最常用的方法就是使用正則表達式,但是正則表達式不能處理所有的html文檔,所以采用迭代方式會更好,下面小編給大家解答下
    2016-08-08

最新評論

济南市| 天长市| 邵东县| 孝昌县| 尚志市| 漯河市| 民乐县| 抚宁县| 静宁县| 花莲县| 灵丘县| 汪清县| 淮北市| 涟水县| 延吉市| 连江县| 阜康市| 禹城市| 新密市| 肇东市| 宿州市| 庄浪县| 吕梁市| 谢通门县| 鲁山县| 修水县| 偏关县| 临夏市| 建昌县| 梨树县| 德化县| 会同县| 东方市| 原平市| 鹤山市| 方山县| 法库县| 班玛县| 皮山县| 西乌珠穆沁旗| 塔城市|