C#學習筆記-協變與逆變

1,泛型接口和委託的逆變與協變
核心:
類型轉換,參數只應用於引用類型

2,關鍵字:協變,out
Foo<父類>=Foo<子類>
Ioo<父類>=Ioo<子類>

3,關鍵字:逆變,in
Foo<子類>=Foo<父類>
Ioo<子類>=Ioo<父類>

返回值協變和參數逆變

    //泛型委託
    delegate T NormalEventHandler<T>(T t);
    //delegate T CovarianceEventHandlerError<out T>(T tOut);//Error錯誤   1   方差無效: 類型參數“T”必須爲“Test.CovarianceEventHandlerError<T>.Invoke(T)”上有效的 逆變式。“T”爲 協變。
    delegate T CovarianceEventHandler<out T>();
    //delegate T ContravarianceEventHandlerError<in T>(T tIn);//Error錯誤 1   方差無效: 類型參數“T”必須爲“Test.ContravarianceEventHandlerError<T>.Invoke(T)”上有效的 協變式。“T”爲 逆變
    delegate void ContravarianceEventHandler<in T>(T tIn);
    delegate T2 ContravarianceEventHandler<in T1,out T2>(T1 tIn);
    //泛型接口
    interface INormal<T> { };
    interface ICovariance<out T> { };
    interface IContravariance<out T> { };

    class ParentClass 
    {
        //基類,父類
        public void Fun()
        {
            MessageBox.Show("ParentClass");
        }
    }

    class ChildClass : ParentClass
    {
        //派生類,子類
        public void Fun()
        {
            MessageBox.Show("ChildClass");
        }
        public void Fun(int i)
        {
            MessageBox.Show("IIII--ChildClass");
        }
    }


    public partial class Form1 : Form
    {
        //協變
        CovarianceEventHandler<ParentClass> CovarianceParent = null;
        CovarianceEventHandler<ChildClass> CovarianceChild = null;
        //逆變
        ContravarianceEventHandler<ParentClass> ContravarianceParent = null;
        ContravarianceEventHandler<ChildClass> ContravarianceChild = null;

        ParentClass ParentFun() 
        {
            ParentClass p = new ParentClass();
            p.Fun();
            return p;
        }

        ChildClass ChildFun()
        {
            ChildClass c = new ChildClass();
            c.Fun(0);
            return c;
        }

        void ParentFun(ParentClass p)
        {
            p.Fun();
        }

        void ChildFun(ChildClass c)
        {
            c.Fun(0);
        }

        public Form1()
        {
            InitializeComponent();
            //協變-父=子
            CovarianceParent = ParentFun;
            CovarianceChild = ChildFun;
            CovarianceParent = CovarianceChild;
            //CovarianceChild = CovarianceParent;//Error,類型無法轉換
            ParentClass obj = CovarianceParent();
            ChildClass obj1 = CovarianceChild();
            //ChildClass obj2 = CovarianceParent();//Error,類型無法轉換
            if (obj is ChildClass && obj1 is ChildClass) 
            {
                MessageBox.Show("success");
            }
            if (obj is ParentClass && obj1 is ParentClass)
            {
                MessageBox.Show("fail");
            }
            obj.Fun();
            obj1.Fun();
            //obj2.Fun();
            //逆變-子=父
            ContravarianceParent = ParentFun;
            ContravarianceChild = ChildFun;
            ContravarianceChild = ContravarianceParent;
            //ContravarianceParent = ContravarianceChild;//Error,類型無法轉換
            ContravarianceChild(new ChildClass());
            ContravarianceParent(new ParentClass());


        }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章