<ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>


      前言

        在.NET 4之前,泛型接口是不變的。.NET 4通過(guò)協(xié)變和抗變?yōu)榉盒徒涌诤头盒臀刑砑恿艘粋€(gè)重要的擴(kuò)展。協(xié)變和抗變指對(duì)參數(shù)和返回值的類型進(jìn)行轉(zhuǎn)換。

        我們來(lái)看下到底什么是協(xié)變什么是抗變:
        如果某個(gè)返回的類型可以由其基類替換,那么這個(gè)類型就是支持協(xié)變的
        如果某個(gè)參數(shù)類型可以由其派生類替換,那么這個(gè)類型就是支持逆變(抗變)的。

      函數(shù)的類型轉(zhuǎn)換

        在理解協(xié)變與抗變之前,我們看下面這個(gè)例子:
      class Program { public static string Tmain(object o) { return "aaa"; } static
      void Main(string[] args) { string a = "aaa"; object b = Tmain(a); } }
      ?

        我們仔細(xì)看下這個(gè)傳值和返回。注意其中發(fā)現(xiàn)了兩次隱式轉(zhuǎn)換。

          1、向函數(shù)傳值的時(shí)候 參數(shù)a從string類型轉(zhuǎn)換成object類型

          2、最后接收返回值的時(shí)候b由string類型轉(zhuǎn)換成object類型

        我們?cè)诜祷睾瘮?shù)來(lái)看。

          1、?String Tmain(object o) 可以轉(zhuǎn)換成string Tmain(string o)

          2、?String Tmain(string o) 可以轉(zhuǎn)換成 object Tmain(string o)

        在這里,也就是說(shuō)函數(shù)輸入的時(shí)候輸入類型可以從object轉(zhuǎn)換成string?;?派生類

        在函數(shù)輸出時(shí),函數(shù)的輸出類型(返回類型)從string轉(zhuǎn)換成object。派生類-基類。

        這里就比較接近泛型接口的協(xié)變和抗變的概念了。我們?cè)倏次覀冮_頭的概念

      ?

        如果某個(gè)返回的類型可以由其基類替換,那么這個(gè)類型就是支持協(xié)變的
        如果某個(gè)參數(shù)類型可以由其派生類替換,那么這個(gè)類型就是支持逆變(抗變)的。

      ?

      理解泛型接口的協(xié)變和抗變(in、out)

        我們下面來(lái)看看泛型接口的協(xié)變及抗變的例子:

        首先我們看下協(xié)變,在C#高級(jí)編程(第十一版)中指出,如果泛型類型用out關(guān)鍵字標(biāo)注,泛型接口就是協(xié)變的。這也就意味著返回類型只能是T。
      /// <summary> /// 標(biāo)識(shí)out,意味著返回類型只能是T /// </summary> /// <typeparam
      name="T"></typeparam> interface Itest<out T> { T Tmain(object value); } public
      class Test : Itest<string> { public string Tmain(object value) { return
      value.ToString(); } }
      ?

      我們調(diào)用時(shí):
      static void Main(string[] args) { Itest<string> itest = new Test(); Itest<
      object> itestObj = itest; }
      ?

        在這里,我們最后接收其返回值的時(shí)候,
      理應(yīng)由string類型進(jìn)行接收的,但是這里我們可以修改,由其基類object類型進(jìn)行替換。也就是在某個(gè)返回類型可以由其基類替換的時(shí)候,也就是支持協(xié)變了。注意其關(guān)鍵點(diǎn)。返回類型、由基類替換派生類。

      ?

      ?

        然后我們?cè)倏纯茨强棺円部煞Q為逆變。在C#高級(jí)編程中指出的概念
      :如果泛型類型用in關(guān)鍵字標(biāo)注,泛型接口就是抗變的。這樣,接口只能把泛型類型T用作其方法的輸入。
        /// <summary> /// 標(biāo)識(shí)in,意味著輸入類型只能是T /// </summary> /// <typeparam
      name="T"></typeparam> interface Itest<in T> { string Tmain(T value); } public
      class Test : Itest<object> { public string Tmain(object value) { return
      value.ToString(); } }class Program { static void Main(string[] args) { Itest<
      object> itest = new Test(); Itest<string> itestStr= itest; } }
      ?

      ?

        這里我們看上面這個(gè)例子,其中返回類型已經(jīng)是固定的string類型了。而泛型接口中的泛型類型用來(lái)作為參數(shù)傳遞了。
      我們?cè)倏凑{(diào)用時(shí),正常傳入object類型的參數(shù),,但是我們修改傳入?yún)?shù)類型為string類型也是可以的。也就是我們?cè)趨⑷雲(yún)?shù)時(shí),參數(shù)可以由其派生類替換的話,那么這個(gè)類也就是支持抗變(逆變)的。注意其中關(guān)鍵點(diǎn)。傳入?yún)?shù),派生類替換基類。

      總結(jié)

        其實(shí)在上述例子及其概念中,我們可以發(fā)現(xiàn),泛型接口的協(xié)變及抗變,也就是將類型參數(shù)返回或者傳入的情況,在這情況下進(jìn)行其類型的隱式轉(zhuǎn)換所遵循的規(guī)律。

          協(xié)變:(使用關(guān)鍵字out)返回類型可以由其基類所替代的時(shí)候,就是支持協(xié)變的。

          抗變(逆變):(使用關(guān)鍵字in)傳入?yún)?shù)類型可以由其派生類所代替的時(shí)候,就是支持抗變(逆變)的。

      ?

        夫?qū)W須靜也,才須學(xué)也,非學(xué)無(wú)以廣才,非志無(wú)以成學(xué)-------諸葛亮

      ?

      ?

                            c#基礎(chǔ)知識(shí)詳解系列
      <https://www.cnblogs.com/hulizhong/p/11205119.html>

      ?

        歡迎大家掃描下方二維碼,和我一起學(xué)習(xí)更多的C#知識(shí)

      ?

      ?

      ?

        

      ?

      友情鏈接
      ioDraw流程圖
      API參考文檔
      OK工具箱
      云服務(wù)器優(yōu)惠
      阿里云優(yōu)惠券
      騰訊云優(yōu)惠券
      京東云優(yōu)惠券
      站點(diǎn)信息
      問(wèn)題反饋
      郵箱:[email protected]
      QQ群:637538335
      關(guān)注微信

        <ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>
          国产强奸乱伦视频 | 日韩欧美人人爽夜夜爽 | 天天躁夜夜躁狠狠躁AV | 嫩草 人人精品免费 | 大逼网| A片在线免费观看视频 | 久久99精品久久久久久秒播九色 | 日逼片| 欧美成人午夜免费视频A片明星 | 某上海少妇3p黑人完整版 |