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

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

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

基本概念

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

關鍵字out和in

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

理解協(xié)變和逆變

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

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

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

這是一段很簡單的子類和父類的關系,我們進行一下簡單的轉化,應該很好理解,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é)變標注,所以可以做正確的轉換。 這里也可以理解出什么時候需要使用in、out關鍵字:當你設計帶有泛型的基類且泛型類型可能存在擴展時,則需要考慮使用in或者out關鍵字修飾。
我們再看看官方的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關鍵字的認識就很簡單明了了??纯崔D換示例:

    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;

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

最后簡單總結下:

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

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

相關文章

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

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

    這篇文章主要為大家詳細介紹了C#如何使用重載方法實現(xiàn)不同類型數(shù)據(jù)的計算,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    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),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    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í)行語句的封裝,可以將封裝的結果像對象一樣傳遞,在傳遞時,這個封裝依然能夠訪問到原上下文。下面這篇文章主要給大家介紹了關于C#中閉包的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    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

最新評論

霞浦县| 云浮市| 山东省| 陆良县| 鄂伦春自治旗| 天等县| 朝阳市| 三穗县| 大埔区| 宁河县| 庄河市| 同江市| 东宁县| 香河县| 深泽县| 翁牛特旗| 绥中县| 牙克石市| 栾城县| 司法| 穆棱市| 科技| 佳木斯市| 辽源市| 库尔勒市| 凤城市| 莎车县| 湘阴县| 盖州市| 白水县| 宣汉县| 兴安县| 镇赉县| 哈密市| 白银市| 昭苏县| 米脂县| 贵德县| 仪陇县| 平乐县| 凤山市|