日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

10分钟浅谈泛型协变与逆变

發布時間:2023/12/24 综合教程 35 生活家
生活随笔 收集整理的這篇文章主要介紹了 10分钟浅谈泛型协变与逆变 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

首先聲明,本文寫的有點粗糙,只讓你了解什么是協變和逆變,沒有深入研究,根據這些年的工作經驗,發現我們在開發過程中,很少會自己去寫逆變和協變,因為自從net 4.0 (Framework 3.0)以后,.net就為我們提供了定義好的逆變與協變。我們只要會使用就可以。協變和逆變都是在泛型中使用的。

什么是逆變與協變呢

可變性是以一種類型安全的方式,將一個對象當做另一個對象來使用。如果不能將一個類型替換為另一個類型,那么這個類型就稱之為:不變量。協變和逆變是兩個相互對立的概念:

如果某個返回的類型可以由其派生類型替換,那么這個類型就是支持協變
如果某個參數類型可以由其基類替換,那么這個類型就是支持逆變的。

看起來你有點繞,我們先準備個“”鳥”類,在準備一個“麻雀”類,讓麻雀繼承鳥類,一起看代碼研究

  /// <summary>
    /// 鳥
    /// </summary>
    public class Bird
    {
        public int Id { get; set; }
    }
    /// <summary>
    /// 麻雀
    /// </summary>
    public class Sparrow : Bird
    {
        public string Name { get; set; }
    }

我們分別取實例化這個類,發現程序是能編譯通過的。

Bird bird1 = new Bird();
Bird bird2 = new Sparrow();
Sparrow sparrow1 = new Sparrow();

//Sparrow sparrow2 = new Bird();//這個是編譯不通過的,違反了繼承性。

但是我們放在集合中,去實例化,是無法通過的

List<Bird> birdList1 = new List<Bird>();

//List<Bird> birdList2 = new List<Sparrow>();//不是父子關系,沒有繼承關系
//一群麻雀一定是一群鳥

那么我們如何去實現在泛型中的繼承性呢??這就引入了協變和逆變得概念,為了保證類型的安全,C#編譯器對使用了outin關鍵字的泛型參數添加了一些限制:

支持協變(out)的類型參數只能用在輸出位置:函數返回值、屬性的get訪問器以及委托參數的某些位置
支持逆變(in)的類型參數只能用在輸入位置:方法參數或委托參數的某些位置中出現。

協變

我們來看下Net “System.Collections.Generic”命名空間下的IEnumerable泛型 接口,會發現他的泛型參數使用了out

現在我們使用下IEnumerable 接口來進行一下上述實力,會發現,我們的泛型有了繼承關系。

IEnumerable<Bird> birdList1 = new List<Bird>();

IEnumerable<Bird> birdList2 = new List<Sparrow>();//協變
//一群麻雀一定是一群鳥

下面我們來自己定義一個協變泛型接口ICustomerListOut<Out T>,讓CustomerListOut泛型類繼承CustomerListOut<Out T>泛型接口。

代碼如下

    /// <summary>
    /// out 協變 只能是返回結果
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public interface ICustomerListOut<out T>
    {
        T Get();

       // void Show(T t);//T不能作為傳入參數
    }

    /// <summary>
    /// 類沒有協變逆變
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class CustomerListOut<T> : ICustomerListOut<T>
    {
        public T Get()
        {
            return default(T);
        }

        public void Show(T t)
        {

        }
    }

我們會發現,在泛型斜變的時候,泛型不能作為方法的參數。我們用自己定義的泛型接口和泛型類進行實例化試試,我們會發現編譯通過

ICustomerListOut<Bird> customerList1 = new CustomerListOut<Bird>();//這是能編譯的
ICustomerListOut<Bird> customerList2 = new CustomerListOut<Sparrow>();//這也是能編譯的,在泛型中,子類指向父類,我們稱為協變

到這里協變我們就學完了,協變就是讓我們的泛型有了子父級的關系。本文開始的時候,協變和逆變,是在C# 4.0以后才有的,那C# 4.0以前我們是怎么寫的呢,那個時候沒有協變?

老版本的寫法

List<Bird> birdList3 = new List<Sparrow>().Select(c => (Bird)c).ToList();//4.0以前的寫法

等學完逆變,本文列出C# 4.0以后的版本中framework已經定義好的協變、逆變 泛型接口,泛型類,泛型委托。

逆變

剛才我們學習了泛型參數用out去修飾,餃子協變,現在來學習下逆變,逆變是使用in來修飾的

這里就是Net 4.0給我們提供的逆變寫法

我們自己寫一個逆變的接口ICustomerListIn<in T> ,在寫一個逆變的泛型類 CustomerListIn<T>:ICustomerListIn<T> ,代碼如下

    /// <summary>
    /// 逆變
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public interface ICustomerListIn<in T>
    {
        //T Get();//不能作為返回值

        void Show(T t);
    }

    public class CustomerListIn<T> : ICustomerListIn<T>
    {
        public T Get()
        {
            return default(T);
        }

        public void Show(T t)
        {
        }
    }

逆變的泛型參數是不能作為泛型方法的返回值的,我們來看下實例化鳥類,和麻雀類,看好使不好使。

ICustomerListIn<Sparrow> customerList2 = new CustomerListIn<Sparrow>();
ICustomerListIn<Sparrow> customerList1 = new CustomerListIn<Bird>();//父類指向子類,我們稱為逆變

ICustomerListIn<Bird> birdList1 = new CustomerListIn<Bird>();
birdList1.Show(new Sparrow());
birdList1.Show(new Bird());

Action<Sparrow> act = new Action<Bird>((Bird i) => { });

到此我們就完全學完了逆變與協變

總結

逆變與協變只能放在泛型接口和泛型委托的泛型參數里面,

在泛型中out修飾泛型稱為協變,協變(covariant 修飾返回值 ,協變的原理是把子類指向父類的關系,拿到泛型中。
在泛型中in 修飾泛型稱為逆變, 逆變(contravariant)修飾傳入參數,逆變的原理是把父類指向子類的關系,拿到泛型中。

NET中自帶的斜變逆變泛型

序號 類別 名稱
1 接口 IEnumerable<out T>
2 委托 Action<in T>
3 委托 Func<out TResult>
4 接口 IReadOnlyList<out T>
5 接口 IReadOnlyCollection<out T>

各位朋友,如果誰還知道,請留言告知

總結

以上是生活随笔為你收集整理的10分钟浅谈泛型协变与逆变的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日批毛片 | 综合图区亚洲 | 国产99精品视频 | 自拍偷拍第5页 | 国产91精品久久久久久久网曝门 | 成人国产在线视频 | 国产一区二区在线电影 | 69视频在线免费观看 | 国产又粗又猛又爽又黄的视频在线观看动漫 | 久久久视| 精精国产xxxx视频在线 | 一起操网站 | 日本一级做a爱片 | 成人xx视频| 国产精品黄色网 | av网站在线免费 | 日韩特黄一级片 | 色婷婷久久久 | 国产大奶在线观看 | 国产一页 | 成人高清视频免费观看 | 四虎在线视频 | 国产精品xx | 91成人福利视频 | 午夜影院在线播放 | 性猛交富婆╳xxx乱大交麻豆 | 91麻豆精品久久久久蜜臀 | 精品久久一区 | 91免费国产视频 | 日韩欧美毛片 | 99久久国产宗和精品1上映 | 欧美激情片一区二区 | 国产精品一区二区自拍 | 日韩av网址大全 | 国产在线观看av | 人人搞人人爱 | 国产一区二区三区在线 | 成人在线视屏 | 国产精品久久av无码一区二区 | cao久久| 青草国产 | 国产三区在线播放 | 日日夜夜狠狠操 | 中文字幕日韩在线播放 | 国产v片在线观看 | 久久爱伊人 | 欧美人妻精品一区二区免费看 | 亚洲乱熟| 日本不卡一区二区在线观看 | 草草影院ccyycom | www.亚洲一区二区三区 | 91jk制服白丝超短裙大长腿 | 在线观看国产日韩 | 欧美毛片网站 | 国产精品无码免费在线观看 | 一区二区三区91 | 一级香蕉视频在线观看 | 日日骑夜夜操 | 成年人在线观看网站 | 色吊丝av中文字幕 | 99午夜| 日韩毛毛片 | 天堂在线 | 国产电影一区在线观看 | www.五月激情 | 成人动漫一区二区三区 | 国产日韩欧美中文字幕 | 久久精品这里只有精品 | 91在线超碰| 国产精品久久九九 | 日韩毛片儿| 国产精美视频 | 成人小视频免费观看 | 一二三四国产精品 | 最好看十大无码av | 国产黄色一级网站 | 久久视频免费观看 | 日本亚洲一区二区三区 | 精品人妻无码专区在线 | 嫩草研究院在线 | 一区二区三区偷拍 | 超碰2| 欧美成人看片黄a免费看 | 欧美一级特黄aa大片 | 日韩国产成人无码av毛片 | 国产99在线观看 | 999精品网站 | 欧美成人福利 | 女人舌吻男人茎视频 | 亚洲成人黄色在线 | 亚洲天堂一区二区在线 | 久久免费国产 | 国产99精品视频 | 我们俩电影网mp4动漫官网 | 日日夜夜天天 | 伊人久久精品视频 | a在线观看免费 | aaa午夜 | 超碰中文字幕在线 |