委托的协变:
class Phone
        {

        }
        class Mobile : Phone
        {    

        }
        delegate Phone PhoneDele();
        class Program
        {
                static void Main(string[] args)
                {
                        Program pro = new Program();
                        PhoneDele pd1 = pro.GetPhone;
                        PhoneDele pd2 = pro.GetMobile;
                }

                public Phone GetPhone()
                {
                        return null;
                }

                public Mobile GetMobile()
                {
                        return null;
                }
        }
委托pd2的返回类型为Phone(父类),GetMobile的返回类型为Mobile(子类),将Mobile(子类)类型的返回值赋给Phone(父类),称为协变。
委托的逆变:
class Phone
        {    

        }
        class Mobile : Phone
        {    

        }
        delegate Phone PhoneDele(Mobile pho);
        class Program
        {
                static void Main(string[] args)
                {
                        Program pro = new Program();
                        PhoneDele pd1 = pro.SetPhone;
                        PhoneDele pd2 = pro.SetMobile;

                }

                public Phone SetPhone(Phone pho)
                {
                        return null;
                }

                public Mobile SetMobile(Mobile mob)
                {
                        return null;
                }
        }
pd1的参数为Mobile类型,SetPhone的参数为Phone类型。实际该句还是将子类型传递给父类型。将类型为子类型Mobile的实际参数传递给类型为父类型Phone的形参,叫做逆变。
这样,看似类型为Phone的参数,实际为Mobile,看起来像装箱。
协逆变都是把子类型赋值给父类型的过程,都符合面向对象规则。
区别在于:1协变关注与返回值,逆变关注与参数;2协变是发生在方法最后对返回值的操作,逆变是发生在方法调用中间的对参数的操作。