亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

C# 泛型的協變和逆變

2019-11-17 02:24:40
字體:
來源:轉載
供稿:網友

C# 泛型的協變和逆變

1. 可變性的類型:協變性和逆變性

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

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

2. C# 4.0對泛型可變性的支持

在C# 4.0之前,所有的泛型類型都是不變量——即不支持將一個泛型類型替換為另一個泛型類型,即使它們之間擁有繼承關系,簡而言之,在C# 4.0之前的泛型都是不支持協變和逆變的。

C# 4.0通過兩個關鍵字:outin來分別支持以協變和逆變的方式使用泛型。

我們來看一段利用了協變類型參數的代碼:

public class BaseClass{    //...}public class DerivedClass : BaseClass{    //...}

下面我們利用協變類型參數,可以執行類似于普通的多態性的分配:

IEnumerable<DerivedClass> d = new List<DerivedClass>();IEnumerable<BaseClass> b = d;

在上面的實例中,在C# 4.0之前是不能正常編譯的,除了對賦值給基類集合時將子類集合做一個強制轉換,但是在運行時仍然會拋出一個類型轉換的異常。

下面我們再看一個關于逆變的實例代碼:

Action<BaseClass> b = (target) => { Console.WriteLine(target.GetType().Name); };Action<DerivedClass> d = b;d(new DerivedClass());

在上面的示例中我們 Action<BaseClass> 類型的委托分配給類型 Action<DerivedClass> 的變量,根據逆變的定義我們可以知道 Action<T> 類型是支持逆變的。

為什么IEnumerable<T>Action<T> 可以分別支持類型的逆變和協變呢?我們查看這兩個類型在 .NET 中的定義:

//IEnumerable<T> 接口的定義(支持協變)public interface IEnumerable<out T> : IEnumerable//Action<T> 委托的定義(支持逆變)public delegate void Action<in T>(T obj);

為了保證類型的安全,C#編譯器對使用了 outin 關鍵字的泛型參數添加了一些限制:

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

3. C#中泛型可變性的限制

1. 不支持類的類型參數的可變性

只有接口和委托可以擁有可變的類型參數。inout 修飾符只能用來修飾泛型接口和泛型委托。

2. 可變性只支持引用轉換

可變性只能用于引用類型,禁止任何值類型和用戶定義的轉換,如下面的轉換是無效的:

  • IEnumerable<int> 轉換為 IEnumerable<object> ——裝箱轉換
  • IEnumerable<short> 轉換為 IEnumerable<int> ——值類型轉換
  • IEnumerable<string> 轉換為 IEnumerable<XName> ——用戶定義的轉換

3. 類型參數使用了 out 或者 ref 將禁止可變性

對于泛型類型參數來說,如果要將該類型的實參傳給使用 out 或者 ref 關鍵字的方法,便不允許可變性,如:

delegate void someDelegate<in T>(ref T t)

這段代碼編譯器會報錯。

4. 可變性必須顯式指定

從實現上來說編譯器完全可以自己判斷哪些泛型參數能夠逆變和協變,但實際卻沒有這么做,這是因為C#的開發團隊認為:

必須由開發者明確的指定可變性,因為這會促使開發者考慮他們的行為將會帶來什么后果,從而思考他們的設計是否合理。

5. 注意破壞性修改

在修改已有代碼接口的可變性時,會有破壞當前代碼的風險。例如,如果你依賴于不允許可變性的is或as操作符的結果,運行在.NET 4時,代碼的行為將有所不同。同樣,在某些情況下,因為有了更多可用的選項,重載決策也會選擇不同的方法。所以在對已有代碼引入可變性時要做好足夠的單元測試以及防御措施。

6. 多播委托與可變性不能混用

下面的代碼能夠通過編譯,但是在運行時會拋出 ArgumentException 異常:

Func<string> stringFunc = () => "";Func<object> objectFunc = () => new object();Func<object> combined = objectFunc + stringFunc;

這是因為負責鏈接多個委托的 Delegate.Combine方法要求參數必須為相同的類型。上面的示例我們可以修改成如下正確的代碼:

Func<string> stringFunc = () => "";Func<object> defensiveCopy = new Func<object>(stringFunc);Func<object> objectFunc = () => new object();Func<object> combined = objectFunc + defensiveCopy;

參考&擴展閱讀

協變和逆變泛型中的協變和逆變委托中的協變和逆變《深入理解C#》:13.3 接口和委托的泛型可變性《Effective C#》:條目29:支持泛型協變和逆變《CLR via C#》:12.5 委托和接口的逆變和協變泛型類型實參


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品99久久久久久人| 国产欧美va欧美va香蕉在| 日韩久久午夜影院| 一道本无吗dⅴd在线播放一区| 日韩电影免费在线观看中文字幕| 一本色道久久88精品综合| 一个色综合导航| 成人h猎奇视频网站| 国产精品热视频| 精品久久久久久久久久| 欧美视频在线免费| 亚洲日本成人网| 国产精品6699| 日韩在线视频网| 亚洲奶大毛多的老太婆| 国产z一区二区三区| 国产婷婷97碰碰久久人人蜜臀| 国语自产精品视频在免费| 日韩在线观看免费全集电视剧网站| 亚洲第一中文字幕在线观看| 97国产精品人人爽人人做| 97人人模人人爽人人喊中文字| 久久国产精彩视频| 欧美日韩国产一区二区三区| 国产午夜精品一区理论片飘花| 欧美亚洲视频一区二区| 日韩精品在线免费播放| 亚洲深夜福利在线| 亚洲开心激情网| 91精品国产777在线观看| 日韩欧美国产高清91| 亚洲区免费影片| 97视频色精品| 国产精品精品视频一区二区三区| 亚洲新声在线观看| 欧美成人中文字幕在线| 欧美第一黄网免费网站| 亚洲在线观看视频| 日本精品视频网站| 性欧美xxxx| 日韩精品免费视频| 91精品国产自产在线| 国产午夜精品美女视频明星a级| 3344国产精品免费看| 疯狂蹂躏欧美一区二区精品| 日韩av中文字幕在线免费观看| 久久青草福利网站| 精品福利视频导航| 国模精品系列视频| 久久影院在线观看| 日韩精品免费综合视频在线播放| 久久精品视频va| 国产视频一区在线| 日韩精品在线免费观看视频| 日韩电影中文字幕在线| 精品国产欧美一区二区三区成人| 中文字幕久久久| 国产不卡一区二区在线播放| 国产精品国语对白| 亚洲欧美在线播放| 亚洲一区久久久| 久久久91精品国产| 在线亚洲午夜片av大片| 日本不卡视频在线播放| 伊人青青综合网站| 欧美日韩免费区域视频在线观看| 中文字幕视频一区二区在线有码| 91亚洲午夜在线| 国产精品久久久久久久久借妻| 俺去亚洲欧洲欧美日韩| 亚洲自拍偷拍在线| 深夜福利一区二区| 国产精品黄页免费高清在线观看| 国外视频精品毛片| 一区二区亚洲欧洲国产日韩| 久久av中文字幕| 国产精品成人免费电影| 国产欧美久久久久久| 岛国av午夜精品| 7777精品久久久久久| 国产精品免费一区二区三区都可以| 7777精品久久久久久| 色婷婷综合久久久久| 亚洲国产一区二区三区在线观看| 国产精品美女主播在线观看纯欲| 亚洲免费一在线| 国产美女高潮久久白浆| 国产精品观看在线亚洲人成网| 亚洲精品xxxx| 久久精品国产亚洲| 国产精品香蕉国产| 91国语精品自产拍在线观看性色| 国产精品男女猛烈高潮激情| 亚洲free性xxxx护士白浆| 久久视频在线看| 亚洲色图av在线| 中文字幕日韩欧美精品在线观看| 日韩av在线免费观看一区| 精品小视频在线| 国产精品高清在线| 欧美高清视频免费观看| 欧美午夜宅男影院在线观看| 欧美成人精品一区| 亚洲a区在线视频| 国产欧美日韩精品丝袜高跟鞋| 欧美另类交人妖| 日韩成人激情在线| 精品亚洲一区二区| 国产成人综合av| 精品性高朝久久久久久久| 欧美高清videos高潮hd| 超碰精品一区二区三区乱码| 国产精品高精视频免费| 亚洲一区精品电影| 美乳少妇欧美精品| 日韩欧美黄色动漫| 啪一啪鲁一鲁2019在线视频| 亚洲精品国精品久久99热一| 亚洲欧美www| 日韩欧美福利视频| 亚洲国产欧美一区二区丝袜黑人| 中文在线资源观看视频网站免费不卡| 久久午夜a级毛片| 欧美亚洲国产另类| 亚洲精品国产suv| 国产精品入口夜色视频大尺度| 亚洲最新av在线网站| 中文字幕自拍vr一区二区三区| 91视频九色网站| 91最新国产视频| 中文字幕日韩在线观看| 国产免费一区视频观看免费| 情事1991在线| 成人精品在线观看| 成人国产精品色哟哟| 欧美午夜电影在线| 欧美精品国产精品日韩精品| 深夜福利一区二区| 亚洲最大在线视频| 亚洲精品久久久久中文字幕二区| 亚洲第一精品电影| 国产精品视频色| 日韩在线激情视频| 精品久久久一区二区| 成人97在线观看视频| 日韩暖暖在线视频| 91精品久久久久久久久中文字幕| 日韩黄色在线免费观看| 国产成人精品在线视频| 精品一区精品二区| 亚洲视频999| 久久国产精品视频| 中文字幕欧美视频在线| 精品国产网站地址| 成人夜晚看av| 91精品国产91久久久| 欧美国产亚洲视频| 亚洲人线精品午夜| 国产精品视频导航| 国产在线高清精品| 中文字幕日韩精品在线观看| 久久精品国产电影| 亚洲尤物视频网| 亚洲免费成人av电影|