C# 泛型接口的抗變和協(xié)變
1, 泛型接口的協(xié)變
如果泛型類型用out關(guān)鍵字標(biāo)注,泛型接口就是協(xié)變的。這也意味著返回類型只能是T。
泛型接口的抗變
如果泛型類型用in關(guān)鍵字標(biāo)注,泛型接口就是抗變的。這樣,接口只能把泛型類型T用作其方法的輸入,即方法的參數(shù)。
這是泛型接口的抗變和協(xié)變的定義,那我們下面來用代碼說明,直接上代碼,
/// <summary>
/// 泛型接口
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IDisplay< T >
{
void Show(T item);
}
/// <summary>
/// 實(shí)現(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, 上面定義了接口和實(shí)現(xiàn)了接口,接下來我們來測試實(shí)現(xiàn)了接口的類,上代碼
class Program
{
static void Main(string[] args)
{
// 用子類實(shí)例化泛型類(簡稱子類對象)
IDisplay<SubClass> sub1 = new ShapDisplay<SubClass>();
// 用父類實(shí)例化泛型類(簡稱父類對象)
IDisplay<ParentClass> par1 = new ShapDisplay<ParentClass>();
// 用父類類型接收子類對象(子類對象→父類類型)協(xié)變
IDisplay<ParentClass> parent = sub1;
// 用子類類型接收父類對象(父類對象→子類類型)抗變
IDisplay<SubClass> sub = par1;
Console.ReadKey();
}
}
我們會(huì)發(fā)現(xiàn)代碼行12和15會(huì)報(bào)錯(cuò),編譯不過,為什么呢?
原因很簡單,因?yàn)槲覀冊谧钌厦媸沁@樣定義接口的時(shí)候,沒有加out也沒有加in,即泛型接口默認(rèn)不會(huì)支持抗變和協(xié)變,所以編譯會(huì)報(bào)錯(cuò)。
好,那我們接下來給泛型接口修改一下,如下代碼
/// <summary>
/// 泛型接口
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IDisplay<out T>
{
void Show(T item);
}
泛型前面加上out之后,會(huì)發(fā)現(xiàn)接口中的Show會(huì)報(bào)錯(cuò),這又是為何呢?
根據(jù)泛型接口的協(xié)變,如果泛型類型用out關(guān)鍵字標(biāo)注,這意味著返回類型只能是T。也就是說方法的返回類型應(yīng)該是T,而我們Show方法中,方法的參數(shù)是T,所以不符合規(guī)定,報(bào)錯(cuò)。
那我們再來修改代碼,如下
/// <summary>
/// 泛型接口
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IDisplay<in T>
{
void Show(T item);
}
接口完全沒問題,但是,囧,main方法中12行依然報(bào)錯(cuò),wtf?
因?yàn)榉盒皖愋褪怯胕n來標(biāo)注的,這表示該泛型只支持抗變,12行代碼是協(xié)變,所以會(huì)報(bào)錯(cuò)。
到此,泛型接口的抗變和協(xié)變也就解釋完畢,總結(jié)如下3點(diǎn),
①泛型接口,如果泛型類型前沒有關(guān)鍵字out或者in來標(biāo)注,則該泛型接口不支持抗變和協(xié)變,即只能是什么對象指向什么類型。
②如果泛型接口,泛型類型前有關(guān)鍵字out標(biāo)注,則表示其方法的輸出為T類型,也就是方法的返回值。同時(shí)該泛型接口支持協(xié)變,即,可以用父類的類型指向子類的對象。
③如果泛型接口,泛型類型前面有關(guān)鍵字in標(biāo)注,則表示其方法的輸入為T類型,也就是方法的參數(shù)。該泛型接口支持抗變,也就是可以用子類的類型指向父類的對象。
以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時(shí)也希望多多支持腳本之家!
- C#泛型的使用及示例詳解
- C#泛型詳解及關(guān)鍵字作用
- C#泛型運(yùn)作原理的深入理解
- C# 泛型集合的自定義類型排序的實(shí)現(xiàn)
- 詳解c# 泛型類的功能
- 詳細(xì)介紹C# 泛型
- 詳解C#泛型的類型參數(shù)約束
- 詳解C# 泛型中的數(shù)據(jù)類型判定與轉(zhuǎn)換
- C#泛型類型知識講解
- C#語法之泛型的多種應(yīng)用
- C#泛型設(shè)計(jì)需要注意的一個(gè)小陷阱
- C#泛型概念的簡介與泛型的使用
- C#泛型類創(chuàng)建與使用的方法
- C# 泛型的約束
- C# 泛型參數(shù)轉(zhuǎn)換
- c#中的泛型委托詳解
- C#的泛型方法解析
- C#泛型詳解
相關(guān)文章
C#使用stackalloc分配堆棧內(nèi)存和非托管類型詳解
這篇文章主要為大家介紹了C#使用stackalloc分配堆棧內(nèi)存和非托管類型詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪<BR>2022-12-12
C#使用DevExpress中的XtraCharts控件實(shí)現(xiàn)圖表
這篇文章介紹了C#使用DevExpress中的XtraCharts控件實(shí)現(xiàn)圖表的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05

