C# 泛型接口的抗變和協(xié)變
1, 泛型接口的協(xié)變
如果泛型類型用out關鍵字標注,泛型接口就是協(xié)變的。這也意味著返回類型只能是T。
泛型接口的抗變
如果泛型類型用in關鍵字標注,泛型接口就是抗變的。這樣,接口只能把泛型類型T用作其方法的輸入,即方法的參數(shù)。
這是泛型接口的抗變和協(xié)變的定義,那我們下面來用代碼說明,直接上代碼,
/// <summary> /// 泛型接口 /// </summary> /// <typeparam name="T"></typeparam> public interface IDisplay< T > { void Show(T item); } /// <summary> /// 實現(xiàn)泛型接口IDisaplay /// </summary> /// <typeparam name="T"></typeparam> public class ShapDisplay<T> : IDisplay<T> { public void Show(T item) { Console.WriteLine("測試成功!"); } } /// <summary> /// 父類 /// </summary> public class ParentClass { } /// <summary> /// 子類 /// </summary> public class SubClass : ParentClass { }
2, 上面定義了接口和實現(xiàn)了接口,接下來我們來測試實現(xiàn)了接口的類,上代碼
class Program { static void Main(string[] args) { // 用子類實例化泛型類(簡稱子類對象) IDisplay<SubClass> sub1 = new ShapDisplay<SubClass>(); // 用父類實例化泛型類(簡稱父類對象) IDisplay<ParentClass> par1 = new ShapDisplay<ParentClass>(); // 用父類類型接收子類對象(子類對象→父類類型)協(xié)變 IDisplay<ParentClass> parent = sub1; // 用子類類型接收父類對象(父類對象→子類類型)抗變 IDisplay<SubClass> sub = par1; Console.ReadKey(); } }
我們會發(fā)現(xiàn)代碼行12和15會報錯,編譯不過,為什么呢?
原因很簡單,因為我們在最上面是這樣定義接口的時候,沒有加out也沒有加in,即泛型接口默認不會支持抗變和協(xié)變,所以編譯會報錯。
好,那我們接下來給泛型接口修改一下,如下代碼
/// <summary> /// 泛型接口 /// </summary> /// <typeparam name="T"></typeparam> public interface IDisplay<out T> { void Show(T item); }
泛型前面加上out之后,會發(fā)現(xiàn)接口中的Show會報錯,這又是為何呢?
根據(jù)泛型接口的協(xié)變,如果泛型類型用out關鍵字標注,這意味著返回類型只能是T。也就是說方法的返回類型應該是T,而我們Show方法中,方法的參數(shù)是T,所以不符合規(guī)定,報錯。
那我們再來修改代碼,如下
/// <summary> /// 泛型接口 /// </summary> /// <typeparam name="T"></typeparam> public interface IDisplay<in T> { void Show(T item); }
接口完全沒問題,但是,囧,main方法中12行依然報錯,wtf?
因為泛型類型是用in來標注的,這表示該泛型只支持抗變,12行代碼是協(xié)變,所以會報錯。
到此,泛型接口的抗變和協(xié)變也就解釋完畢,總結如下3點,
①泛型接口,如果泛型類型前沒有關鍵字out或者in來標注,則該泛型接口不支持抗變和協(xié)變,即只能是什么對象指向什么類型。
②如果泛型接口,泛型類型前有關鍵字out標注,則表示其方法的輸出為T類型,也就是方法的返回值。同時該泛型接口支持協(xié)變,即,可以用父類的類型指向子類的對象。
③如果泛型接口,泛型類型前面有關鍵字in標注,則表示其方法的輸入為T類型,也就是方法的參數(shù)。該泛型接口支持抗變,也就是可以用子類的類型指向父類的對象。
以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持我們!
上一篇:C#導入導出Excel數(shù)據(jù)的兩種方法
欄 目:C#教程
本文標題:C# 泛型接口的抗變和協(xié)變
本文地址:http://mengdiqiu.com.cn/a1/C_jiaocheng/5822.html
您可能感興趣的文章
- 01-10C#通過反射獲取當前工程中所有窗體并打開的方法
- 01-10關于ASP網(wǎng)頁無法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#停止線程的方法
- 01-10WinForm實現(xiàn)仿視頻 器左下角滾動新聞效果的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的方法
- 01-10C#實現(xiàn)清空回收站的方法
- 01-10C#實現(xiàn)讀取注冊表監(jiān)控當前操作系統(tǒng)已安裝軟件變化的方法
- 01-10C#實現(xiàn)多線程下載文件的方法


閱讀排行
本欄相關
- 01-10C#通過反射獲取當前工程中所有窗體并
- 01-10關于ASP網(wǎng)頁無法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實現(xiàn)txt定位指定行完整實例
- 01-10WinForm實現(xiàn)仿視頻 器左下角滾動新
- 01-10C#停止線程的方法
- 01-10C#實現(xiàn)清空回收站的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的
- 01-10C#實現(xiàn)讀取注冊表監(jiān)控當前操作系統(tǒng)已
隨機閱讀
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 01-10SublimeText編譯C開發(fā)環(huán)境設置
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-11ajax實現(xiàn)頁面的局部加載
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 04-02jquery與jsp,用jquery
- 01-10C#中split用法實例總結
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-10delphi制作wav文件的方法