<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      享受代碼,享受人生

      SOA is an integration solution. SOA is message oriented first.
      The Key character of SOA is loosely coupled. SOA is enriched
      by creating composite apps.
        博客園  :: 首頁  :: 新隨筆  :: 聯系 :: 訂閱 訂閱  :: 管理

      Covariance and Contravariance

      Posted on 2010-06-20 14:36  idior  閱讀(3841)  評論(8)    收藏  舉報

      協變和逆變,這兩個詞的翻譯實在很難表達出他們的真實含義。其實他們是繼承和多態的衍生物,而且在.Net 1.0 和2.0中都提供了某種程度的支持,只是在.Net 4.0中支持的更加完善了。

      簡單說來,協變和逆變就是希望支持更多情況的隱式類型轉換,使得我們的編程更加方便,而通常來說只有具備繼承關系的兩個對象才可以發生隱式類型轉換,如Base b=new Derived(). 協變和逆變則使得更多的類型之間可以發生隱式類型轉換,如通過協變以下代碼可以正常工作:

                 Func<Derived> dFunc=GetDFunc();
                 Func<Base> bFunc = dFunc;
      
                 IEnumerable<Derived> dEnum=GetDEnum();
                 IEnumerable<Base> bEnum = dEnum;
      

       

      那么我們為什么需要這種功能呢?讓我們從一個多態的例子開始:

       

           abstract class Animal
           {
               internal abstract void Eat();
           }
      
      
           abstract class Mammal : Animal
           {
           }
      
           class Tiger : Mammal
           {
               internal override void Eat()
               {
                   Console.WriteLine("Tiger eat");
               }
           }
      
      class Program
      {
          static void Main(string[] args)
          {
              Tiger tiger = new Tiger();
              FeedAnimal(tiger);
          }
      
          static void FeedAnimal(Animal animal)
          {
              animal.Eat();
          }
      }
      

      雖然FeedAnimal方法接受的參數類型為Animal ,但是當我們傳入一個Tiger 的實例,方法能夠編譯通過,并得到正確的執行。這是一個典型的多態運用。之所以能夠這么做是因為Tiger 繼承于Animal ,在FeedAnimal方法中對Animal對象的各種操作,Tiger 對象同樣支持,而不會發生調用了animal的某個方法A,而tiger中不存在A方法的情況。 那么如果我們把這一原則推而廣之,就出現了協變這一概念。

             static void FeedAnimal(Func<Animal> animalCreator)
             {
                 var animal=animalCreator();
                 animal.Eat();
             }
      
             static Tiger CreateTiger()
             {
                 return new Tiger();
             }
      

      現在我們讓FeedAnimal方法接受一個能夠返回Animla的delegate,而同時又創建了一個能夠返回Tiger的方法。按照之前的推理,FeedAnimal方法無非就是對delegate中返回的Animal對象進行各種操作,那么如果給它一個返回Tiger對象的delegate,也應該能夠正常的工作。所以下面這段代碼是可以在.NET 2.0中工作的。

      class Program
      {
          static void Main(string[] args)
          {
              FeedAnimal(CreateTiger);
          }
      }
      

      這就是所謂的協變,我們希望兩個對象之間,除了繼承關系外也能做隱式類型的轉換,因為我們認為這種轉換是合理的,是類型安全的。

      大家可能很奇怪,如果.Net 2.0就已經支持了以上的代碼,那么4.0又搞了些什么?

      先來看看下面的代碼:

       
      class Program
      {
          static void Main(string[] args)
          {
              Tiger tiger = new Tiger();
              FeedAnimal(tiger);
          }
      
          static void FeedAnimal(Animal animal)
          {
              Console.WriteLine("Feed Animal");    
          }
       
          static void FeedAnimal(Mammal mammal)
          {
              Console.WriteLine("Feed Mamal");  
          } 
      }
       

      以上這段代碼的輸出結果是 Feed Mammal,當碰到兩個匹配的重載方法時,.Net編譯器選擇了形參類型在繼承樹上更接近自己的方法。可是如果我們把Animal改成Func<Animal> 以下代碼就編譯出錯了,編輯器不知道選擇哪個方法作為匹配。

       

      class Program
      {
          static void Main(string[] args)
          {
              FeedAnimal(CreateTiger);
          }
          static Tiger CreateTiger() { return new Tiger(); } 
        
          static void FeedAnimal(Func<Animal> animalCreator)
          {
              var animal=animalCreator();
              animal.Eat();
          }
      
          static void FeedAnimal(Func<Mammal> animalCreator)
          {
              var animal = animalCreator();
              animal.Eat();
          }
      

      究其根本,在C# 2.0中你無法實現以下delegate間的隱式類型轉換

      Func<Tiger> tFunc = CreateTiger;
      Func<Animal> aFunc = tFunc;
      

       

      而C# 4.0, 使得上述代碼能夠成功運行,之前的兩個方法他也能夠做出正確的選擇。這是通過out關鍵字實現的。 注意Func<TResult> 這個delegate在C# 2.0和4.0中的定義是不同的:

           //C# 2.0
           public delegate TResult Func<TResult>();
      
           //C# 4.0
           public delegate TResult Func<out TResult>();
      

      out關鍵字表示該類型用于返回值,而返回值可以發生協變,因為一個方法如果能夠接受一個返回Animal的delegate,那么他必然也可以接受一個返回Tiger的delegate,因為他對animla的操作同樣可以作用于tiger上。

      既然delegate能夠支持協變,那么interface也應該給予支持,因為它無非就是多個delegate罷了。

      以下代碼在C# 2.0中式不能通過編譯的, 這樣看來interface還不如delegate支持的好。

      static void Main(string[] args)
      {
          List<Tiger> tigers = new List<Tiger>();
          FeedAnimals(tigers);          
      }
      
      static void FeedAnimals(IEnumerable<Animal> animals)
      {
          foreach (var animal in animals)
              animal.Eat();
      }
      

      下面的代碼也就更加不行了:

      List<Tiger> tigers = new List<Tiger>();
      IEnumerable<Animal> animlas = tigers;

       

      到了C# 4.0中,由于out關鍵字的緣故,以上兩段代碼都能正常工作了。而IEnumerable<T>的定義也被改為

       

           public interface IEnumerable<out T> : IEnumerable
           {                     
               IEnumerator<T> GetEnumerator();
           }
      

       

      之前舉得例子都是描述協變的,其實逆變無非就是擴大了輸入參數的類型轉換的可能,不過方向是反的。

        static void FeedAnimal(Animal animal)
        {
            animal.Eat();
        }
      
        static void Execute(Action<Mammal> tAct)
        {
            tAct(new Tiger());
        }
      

       

      在Execute方法中, 我們接受一個類型為Action<Mammal> 的delegate,我們在使用這個delegate時,可以傳入各種類型的Mammal,比如Tiger, Lion。如果我們傳入的delegate能夠作用于Animal對象,那么他自然可以作用于Tiger, Lion。 所以我們可以傳入一個輸入類型更抽象的delegate。因此,在逆變的支持下我們可以寫出以下代碼。

       

            static void Main(string[] args)
            {
                Action<Animal> aAct = FeedAnimal;
                Action<Mammal> mAct = aAct;
                
                Execute(aAct);
            }
      

       

      參考資料:

      eric's series on covariance and contravariance 


      主站蜘蛛池模板: 国产天堂亚洲国产碰碰| 起碰免费公开97在线视频| 国产热A欧美热A在线视频| 中文字幕一区有码视三区| 国产成人精品亚洲精品日日| а∨天堂一区中文字幕| 久久精品日日躁夜夜躁| 日韩精品中文女同在线播放| 在线观看亚洲欧美日本| 亚洲性日韩精品一区二区| 日韩av毛片福利国产福利| 人人爽亚洲aⅴ人人爽av人人片| 欧美人与zoxxxx另类| 亚洲天堂成人黄色在线播放| 日本精品极品视频在线| 国产成人综合色视频精品| 国产精品老熟女露脸视频| 午夜国产精品福利一二| 亚洲成a人无码av波多野| 国产精品永久免费无遮挡| 亚洲精品日本久久久中文字幕| 亚洲国产一区二区三区最新| 国产成人精品国产成人亚洲| 日本极品少妇videossexhd| 久久国产成人高清精品亚洲| 精品亚洲国产成人性色av| 久久中精品中文字幕入口| 最近中文国语字幕在线播放| 精品一区二区三区四区色| 成年女人免费毛片视频永久| 久久青青草原精品国产app| 国产精品国产精品偷麻豆| 久操资源站| 色噜噜一区二区三区| 久草热大美女黄色片免费看| 国产成人高清精品免费软件| 起碰免费公开97在线视频 | 久久天天躁综合夜夜黑人鲁色| 中文字幕人妻不卡精品| 老子午夜精品888无码不卡| 国产亚洲精品第一综合另类无码无遮挡又大又爽又黄的视频 |