一句話清晰總結(jié)C#的協(xié)變和逆變
看到過幾篇協(xié)變和逆變的文章,但是總覺得寫得不夠清晰,文章這東西注重要是要把自己想表達(dá)的觀點(diǎn)表達(dá)出來,這個(gè)過程應(yīng)該是把復(fù)雜的東西消化出來從而簡(jiǎn)單化,清晰化,而不是故弄玄虛,反其道而行之,下面我們言歸正傳啦。
我們先來看一段MSDN原文給協(xié)變,逆變和變體下個(gè)定義:
A generic interface or delegate is called variant if its generic parameters are declared covariant or contravariant. Both C# and Visual Basic enable you to create your own variant interfaces and delegates.
如果泛型接口或委托的泛型參數(shù)聲明為協(xié)變或逆變,則將該泛型接口或委托稱為“變體”。 C# 和 Visual Basic 都允許您創(chuàng)建自己的變體接口和委托。
通俗解釋:
變體定義:帶有協(xié)變或逆變參數(shù)的泛型接口或委托。也就是說協(xié)變和逆變主要關(guān)注點(diǎn)在泛型接口或委托。
那什么又是協(xié)變和逆變呢?
我們先來看下面一個(gè)來自MSDN的例子:
1 // 協(xié)變
2 IEnumerable<string>strings = new List<string>();
3 IEnumerable<object> objects = strings;
大家看到了么一個(gè)聲明為IEnumerable<string>的 接口類型被賦給了一個(gè)更低 級(jí)別的IEnumerable<object>.
對(duì),這就是協(xié)變。再來看一個(gè)例子:
class Base
{
??? public static void PrintBases(IEnumerable<Base> bases)
??? {
??????? foreach(Base b in bases)
??????? {
??????????? Console.WriteLine(b);
??????? }
??? }
}
?
class Derived : Base
{
??? public static void Main()
??? {
??????? List<Derived> dlist = new List<Derived>();
?
??????? Derived.PrintBases(dlist);//由于IEnumerable<T>接口是協(xié)變的,所以PrintBases(IEnumerable<Base> bases)
?????????????????????????????? ?? //可以接收一個(gè)更加具體化的IEnumerable<Derived>作為其參數(shù)。
??????? IEnumerable<Base> bIEnum = dlist;
??? }
}下面給協(xié)變下個(gè)定義:
協(xié)變:讓一個(gè)帶有協(xié)變參數(shù)的泛型接口(或委托)可以接收類型更加精細(xì)化,具體化的泛型接口(或委托)作為參數(shù),可以看成OO中多態(tài)的一個(gè)延伸。
// 逆變
// Assume that the following method is in the class:
// static void SetObject(object o) { }
Action<object> actObject = SetObject;
Action<string> actString = actObject;
//委托actString中以后要使用更加精細(xì)化的類型string不能再使用object啦!
string strHello(“Hello”);
actString(strHello);大家看到了么?一個(gè)聲明為Action<object>的類型被賦給了一個(gè)Action<string>,大家都知道,Action<T>接收參數(shù),沒有返回值,所以其中的object和string是其參數(shù),這個(gè)過程其實(shí)就是參數(shù)的約束更加強(qiáng)了,也就是說讓參數(shù)類型更加精細(xì)化。下面我們來給逆變下個(gè)定義:
逆變:讓一個(gè)帶有協(xié)變參數(shù)的泛型接口(或委托)可以接收粒度更粗的泛型接口或委托作為參數(shù),這個(gè)過程實(shí)際上是參數(shù)類型更加精細(xì)化的過程。
一句話總結(jié):協(xié)變讓一個(gè)粗粒度接口(或委托)可以接收一個(gè)更加具體的接口(或委托)作為參數(shù)(或返回值);逆變讓一個(gè)接口(或委托)的參數(shù)類型(或返回值)類型更加具體化,也就是參數(shù)類型更強(qiáng),更明確。
通常,協(xié)變類型參數(shù)可用作委托的返回類型,而逆變類型參數(shù)可用作參數(shù)類型。 對(duì)于接口,協(xié)變類型參數(shù)可用作接口的方法的返回類型,而逆變類型參數(shù)可用作接口的方法的參數(shù)類型。
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接
相關(guān)文章
快速解決owin返回json字符串多帶了雙引號(hào)"多了重string轉(zhuǎn)義字符串
下面小編就為大家?guī)硪黄焖俳鉀Qowin返回json字符串多帶了雙引號(hào)"多了重string轉(zhuǎn)義字符串。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-08-08
C#實(shí)現(xiàn)IDisposable接口釋放非托管資源
這篇文章主要為大家介紹了C#實(shí)現(xiàn)IDisposable接口釋放非托管資源,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05
.Net多進(jìn)程通信共享內(nèi)存映射文件Memory?Mapped
這篇文章主要介紹了.Net多進(jìn)程通信共享內(nèi)存映射文件Memory?Mapped的使用示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04
c#使用ManagedWifi查看當(dāng)前Wifi信號(hào)并選擇wifi的示例
這篇文章主要介紹了c#使用ManagedWifi查看當(dāng)前Wifi信號(hào)并選擇wifi的示例,需要的朋友可以參考下2014-04-04
Unity使用LineRender實(shí)現(xiàn)簽名效果
這篇文章主要為大家詳細(xì)介紹了Unity使用LineRender實(shí)現(xiàn)簽名效果,制作簽名功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10
C#基于正則表達(dá)式刪除字符串中數(shù)字或非數(shù)字的方法
這篇文章主要介紹了C#基于正則表達(dá)式刪除字符串中數(shù)字或非數(shù)字的方法,涉及C#針對(duì)數(shù)字的簡(jiǎn)單正則匹配相關(guān)操作技巧,需要的朋友可以參考下2017-06-06
如何用WindowsForm給窗口添加一些簡(jiǎn)單的動(dòng)畫效果
這篇文章主要介紹了如何用WindowsForm給窗口添加一些簡(jiǎn)單的動(dòng)畫效果,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-07-07
Unity實(shí)現(xiàn)粒子光效導(dǎo)出成png序列幀
這篇文章主要為大家詳細(xì)介紹了Unity實(shí)現(xiàn)粒子光效導(dǎo)出成png序列幀,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-03-03

