c#中關於協變性和逆變性(又叫抗變)幫助理解


  今天回憶了之前看的《深入理解C#》這本書中的泛型章節,其中對泛型的可變性的理解。泛型可變性分兩種:協變和逆變。逆變也又稱為抗變。

 怎么理解這兩個名詞的意思:

  ①:協變即為在泛型接口類型中使用out標識的類型參數。協變的字面意思是“與變化的方向相同”②逆變那就是用in來標識的泛型接口類型的類型參數。逆變的字面意思是“與變化的方向相反”

  需要注意的是無論是協變還是逆變也只能在泛型接口中來使用。

  先來舉個基本的例子,來加強你對可變性的理解。在C#中有隱式類型轉換,比如:

  string str = "nibian";
  object str1 = str;
  Console.WriteLine(str1);

  

  大家都知道string類型是object類型的子類型,即string->object為子->父;從子類型到父類型的轉換是隱式類型轉換。

舉個例子:

 interface IDemo<out T>
    {
        T Method(string str);
    }
    class One : IDemo<string>
    {
        public string Method(string str)
        {
            return str;
        }
    }
    class Two : IDemo<object>
    {
        public object Method(string str)
        {
            return str;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            IDemo<string> one = new One();
            IDemo<object> two;
            two = one;
            Console.WriteLine(two.Method("2222"));
        }
    }

  

因為string是object類型的子類,在這里IDemo<string>和IDemo<object>類型之間也存在着類型轉換的,從IDemo<string>向IDemo<object>進行的轉換可以看成是子類型向父類型的隱式轉換,它的這個用法就是協變。(這里必須要用out)

相反的我們在來看一下有關逆變的代碼:

 interface IDemo<in T>
    {
        string Method(T str);
    }
    class One : IDemo<string>
    {
        public string Method(string str)
        {
            return str;
        }
    }
    class Two : IDemo<object>
    {
        public string Method(object str)
        {
            return str.ToString();
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            IDemo<object> two = new Two();
            IDemo<string> one;
            one = two;
            Console.WriteLine(one.Method("2222"));
        }
    }

  同樣的從IDemo<object>類型向IDemo<string>類型的轉換,但是在這里我們卻將父類型隱式轉換為子類型的用法叫逆變。(這里必須要用in)

總結:協變和逆變就是在泛型接口類型將類型參數作為輸入和輸出的情況下,對類型間進行隱式轉換的規律。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM