欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(shí)間: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é)變和逆變

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

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

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

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

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

    //error 編譯錯(cuò)誤
    //Dog dog2 = animal;

那么我們做一點(diǎn)變化。

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

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

感覺到一點(diǎn)問題沒?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é)變標(biāo)注,所以可以做正確的轉(zhuǎn)換。 這里也可以理解出什么時(shí)候需要使用in、out關(guān)鍵字:當(dāng)你設(shè)計(jì)帶有泛型的基類且泛型類型可能存在擴(kuò)展時(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)ⅲ胕n表示逆變,F(xiàn)unc的第二個(gè)泛型類型TResult是出參,用out表示協(xié)變。
那么這樣看起來對in、out關(guān)鍵字的認(rèn)識就很簡單明了了??纯崔D(zhuǎn)換示例:

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

    //error 編譯錯(cuò)誤。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 編譯錯(cuò)誤。out
    //Func<int, Dog> func_dog_2 = func_animal;

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

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

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

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

相關(guān)文章

  • C#中累加器函數(shù)Aggregate用法實(shí)例

    C#中累加器函數(shù)Aggregate用法實(shí)例

    這篇文章主要介紹了C#中累加器函數(shù)Aggregate用法,實(shí)例分析了C#中累加器的實(shí)現(xiàn)與使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • C# List<T> Contains<T>()的用法小結(jié)

    C# List<T> Contains<T>()的用法小結(jié)

    本篇文章主要是對C#中List<T> Contains<T>()的用法進(jìn)行了總結(jié)介紹,需要的朋友可以過來參考下,希望對大家有所幫助
    2014-01-01
  • c# EnumHelper枚舉常用操作類

    c# EnumHelper枚舉常用操作類

    在項(xiàng)目中需要把枚舉填充到下拉框中,所以使用統(tǒng)一的方法實(shí)現(xiàn),測試代碼如下,需要的朋友可以參考下
    2016-11-11
  • 獲得.net控件的windows句柄的方法

    獲得.net控件的windows句柄的方法

    有一個(gè)簡單的獲得控件的句柄的竅門。你將窗體設(shè)置為鼠標(biāo)可捕獲,那么你的窗口句柄可以通過使用Windows API捕獲。 這個(gè)想法在以下的GetHWnd函數(shù)中實(shí)現(xiàn):
    2013-04-04
  • C#實(shí)現(xiàn)會移動(dòng)的文字效果

    C#實(shí)現(xiàn)會移動(dòng)的文字效果

    這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)會移動(dòng)的文字效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • C#開發(fā)中的垃圾回收機(jī)制簡析

    C#開發(fā)中的垃圾回收機(jī)制簡析

    這篇文章主要為大家詳細(xì)介紹了C#開發(fā)中的垃圾回收機(jī)制,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2015-10-10
  • C# 讀寫XML文件實(shí)例代碼

    C# 讀寫XML文件實(shí)例代碼

    在本篇文章里小編給大家整理的是關(guān)于C# 讀寫XML文件最簡單方法,需要的朋友們可以跟著學(xué)習(xí)參考下。
    2020-03-03
  • C#代碼實(shí)現(xiàn)對AES加密解密

    C#代碼實(shí)現(xiàn)對AES加密解密

    這篇文章主要介紹了C#代碼實(shí)現(xiàn)對AES加密解密的相關(guān)資料,AES是一個(gè)新的可以用于保護(hù)電子數(shù)據(jù)的加密算法,需要的朋友可以參考下
    2015-12-12
  • Winform讓DataGridView左側(cè)顯示圖片

    Winform讓DataGridView左側(cè)顯示圖片

    本文主要介紹在如何讓DataGridView左側(cè)顯示圖片,這里主要講解重寫DataGridView的OnRowPostPaint方法,需要的朋友可以參考下。
    2016-05-05
  • C#使用iTextSharp將PDF轉(zhuǎn)成文本的方法

    C#使用iTextSharp將PDF轉(zhuǎn)成文本的方法

    這篇文章主要介紹了C#使用iTextSharp將PDF轉(zhuǎn)成文本的方法,涉及C#操作pdf文件的相關(guān)技巧,需要的朋友可以參考下
    2015-05-05

最新評論