一个简单例子理解C#的协变和逆变
一个简单例子理解C#的协变和逆变
关于协变逆变,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
{