关于协变逆变,SolidMango的解释是比较可取的。有了协变,比如,在需要返回IEnumerable<object>类型的时候,可以使用IEnmerable<string>来替代;有了逆变,比如,在需要接收IComparable<string>类型形参方法中,可以使用IComparable<object>类型实参来替代。
协变
先来体会协变。有2个具有继承关系的父类和子类。
public class Animal{public string Name { get; set; }}public class Dog : Animal{public Dog(string dogName){Name = dogName;}}
现在有一个帮助类的方法的形参类型是父类集合IEnumerable<Animal>。
public class MyHelper{public void PRintAnimalNames(IEnumerable<Animal> animals){foreach (var animal in animals){Console.WriteLine(animal.Name);}}}
有了协变,可以在PrintAnimalNames方法中传入IEnumerable<Dog>类型的实参替代IEnumerable<Animal>类型。
static void Main(string[] args){List<Dog> dogs = new List<Dog>(){new Dog("小狗petty"),new Dog("小狗lily")};//协变IEnumerable<Animal> animals = dogs;MyHelper myHelper = new MyHelper();myHelper.PrintAnimalNames(animals);Console.ReadKey();}
可见,在方法中基于基类接口类型的形参,调用该方法的时候可以传入派生类接口类型的实参。
逆变
再来体会逆变。依然是2个具有继承关系的父类和子类。
public class Animal{
新闻热点
疑难解答