C#泛型的協變和抗變

首先我們都知道父類對象可以指向子類對象

    class Document
    {
 
    }
    class OperationGuide:Document
    {
    }
那麼就可以寫成 Document doc = new OperationGuide();
但如果用於泛型就不行了,例如我寫一個泛型類Test,那麼就不能這樣寫了,會報一個隱士轉換錯誤,
Test<Document> doc = new Test<OperationGuide>();
那麼此時泛型的協變和抗變就出現了,協變和抗變只能用在泛型委託和泛型接口上和值類型或引用類型上,,主要是對象參數和返回值的類型進行轉換。
1.泛型接口的協變
如果泛型類型out關鍵字標註,那麼該泛型接口就是協變,也就意味着返回類型只能是T
 interface IDocument<out T>
    {
        string Title { get; set; }
        string Content { get; set; }
    }
 class Test:IDocument<OperationGuide>
    {
   
        private string title;
        private string content;


        public string Title
        {
           get { return title; }
           set { title = value; }
        }


        public string Content
        {
            get { return content; }
            set { content = value; }
        }


        private static Test test;
        public static Test GetTest
        {
            get { return test = new Test(); }
        }
   
    }

 class Program
    {
       
        static void Main(string[] args)
        {
            IDocument<OperationGuide> oper = Test.GetTest;
            IDocument<Document> doc = oper;
            
        }
    }
因爲接口是協變,所以可以把返回值oper賦予doc變量
2.泛型接口的抗變
如果泛型類型用int關鍵字標註,泛型接口就是抗變,這樣,接口只能把泛型類型T用做其方法的輸入
 interface IDocument<in T>
    {
        void ShowInfo(T docInfo);
    }

class Display : IDocument<Document>
    {
        public void ShowInfo(Document doc)
        {
            Console.WriteLine("我是文檔父類"+doc.ToString());
        }
    }

  class Program
    {
       
        static void Main(string[] args)
        {
            OperationGuide operation = new OperationGuide();
            IDocument<Document> doc = new Display();
            IDocument<OperationGuide> oper = doc;
            oper.ShowInfo(operation);
        }
    }
首先實例化一個子對象文檔類,接着就創建一個Display實例賦予doc變量,因爲IDocument是抗變,所以可以把結果賦予泛型子對象變量oper。
簡單的理解泛型接口或委託的協變就是將子對象到父對象的轉換,而抗變就是父對象到子對象的轉換

轉載請註明出處:http://blog.csdn.net/wu5101608/article/details/30707643
AT:Coyote    知識正在蔓延
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章