首页 > 其他分享 >可变性(variance)——协变(convariance),逆变(contravariance),不变(invariance)

可变性(variance)——协变(convariance),逆变(contravariance),不变(invariance)

时间:2022-12-08 13:33:37浏览次数:52  
标签:委托 Factory Dog contravariance Animal 协变 可变性 class

应用在泛型委托,泛型接口上。

一。准备知识——赋值兼容性

      将派生类的对象赋值给基类型变量。

    class Animal {
        public int NumerOfLegs = 4;
    }

    class Dog:Animal {
    }
class Program { static void Main(string[] args) { Animal a1 = new Animal(); Animal a2 = new Dog(); // 派生类变量赋给基类型变量————继承了基类的字段 Console.WriteLine($"Number of dog legs:{a2.NumerOfLegs}"); } }

二。协变

     将委托参数类型的派生类型赋值给委托参数类型的基类型,以下代码编译报错——无法隐式类型转换

    出错原因:泛型委托参数类型虽然存在派生关系,但委托Factory<Dog>与Factory<Animal>间不存在派生关系,所在赋值兼容性不适用。

class Animal {
            public int Legs = 4;
        }

        class Dog : Animal {
        }

        delegate T Factory<T>();    // 有返回值,无参数泛型委托

        class Program {
            // 匹配Factory委托的方法
            static Dog MakeDog() {
                return new Dog();
            }
            static void Main(string[] args) {
                Factory<Dog> dogMaker = MakeDog;         // 使用静态方法给委托赋值
                Factory<Animal> animalMaker = dogMaker;  // 编译报错:无法隐式类型转换
                Console.WriteLine(animalMaker().Legs.ToString());
            }
        }

==》》正式引入协变

      将派生类型用作输出值,可以赋给基类型引用。为了让编译器知道我们的期望,必须使用out标记委托声明中的类型参数

     用下面代码替换上面委托定义行。

delegate T Factory<out T>();

三。逆变

     只作输入参数类型为基类型,可以传入派生类对象

class Animal {
        public int NumberOfLegs = 4;
    }

    class Dog : Animal {
    }

    delegate void Action1<in T>(T a);    // 无返回值,有参数泛型委托

    class Program
    {
        // 匹配Factory委托的方法
        static void ActOnAnimal(Animal a) {
            Console.WriteLine(a.NumberOfLegs);
        }
        static void Main(string[] args) {
            Action1<Animal> act1 = ActOnAnimal; // 使用静态方法给委托赋值
            Action1<Dog> dog1 = act1;           // 基类参数委托赋给派生类参数委托
            dog1(new Dog());                    // 传入派生类对象
        }
    }

四。协变与逆变不同

 

 五。接口的协变与逆变

 

六。关于可变的更多内容

 

七。不变

     

标签:委托,Factory,Dog,contravariance,Animal,协变,可变性,class
From: https://www.cnblogs.com/duju/p/16965582.html

相关文章

  • 《强行让机械波波方程满足伽利略协变的后果就是:》 回复
    《强行让机械波波方程满足伽利略协变的后果就是:》     https://tieba.baidu.com/p/8174836083    5楼@Excalibur!幺模幺正矩阵群? @Henry272@多项式......
  • 重学c#系列——逆变和协变[二十四]
    前言简单整理一下逆变和协变。正文什么是逆变和协变呢?首先逆变和协变都是术语。协变表示能够使用比原始指定的派生类型的派生程度更大的类型。逆变表示能够使用比原......
  • Javascript的字符串不可变性
    JS的字符串不可变指的是字符串值是不变的,只是变量指向的地址变化了,重新在内存中开辟了空间.vara='111';vara='222';此时字符串'111'的空间依然存在内存中,重新开辟......
  • [2022.10.23]String的不可变性
    final关键字代表最终、不可改变的常见四种用法:1.可以用来修饰一个类(不能有任何子类)2.可以用来修饰一个方法(最终方法,不能被覆盖重写)3.还可以用来修饰一个局部变量(对......
  • 协变返回类型
    1.代码示例packagedemo01;classGrain{@OverridepublicStringtoString(){return"Grain[]";}}classWheatextendsGrain{......
  • Rust内部可变性
    InteriorMutabilityMutex和RwLock的作用,除了将类型T包裹起来,提供对该类型数据的多线程安全访问之外,还有一个大的用处:Interiormutability。在Rust中,如果传入类型......
  • 如何应对软件可变性?这4种常用的方法肯定要知道
    摘要:在许多软件系统的开发运行阶段乃至整个生命周期中,软件可变性都是其设计开发者所要面对的基本问题。本文分享自华为云社区《如何应对软件可变性?这4种常用的方法肯定要......