public delegate TResult Func<in T, out TResult>(T arg);
public interface IReadOnlyList<out T> : IEnumerable<T>, IEnumerable
任何能用父类做为输入参数的地方,当然也能用子类作为替换,这叫逆变(Contravariant)。
任何返回子类的地方,当然也能安全的向上转行为父类。这叫协变(Covariant)。
举例说明如下:
1)对于输入参数(in):任何可以输入父类animal的地方,当然可以输入子类dog。
2)对于输出参数(out):输出dog的地方,客户端仅仅把它看作animal来对待。
public abstract class Animal {}
public class Dog:Animal{}
//Covariant
public static void Main()
{
Dog aDog = new Dog();
Animal aAnimal = aDog;
//invariant(不变)
List<Dog> lstDogs = new List<Dog>();
//List<Animal> lstAnimal = lstDogs;
List<Animal> lstAnimal2 = lstDogs.Select(d => (Animal)d).ToList();
//Covariant IEnumerable<out T> 从代码看出协变是安全的
IEnumerable<Dog> someDogs = new List<Dog>();
IEnumerable<Animal> someAnimals = someDogs;
//Contravariant Action<in T> 从代码看出逆变可能不安全
Action<Animal> actionAnimal = new Action<Animal>(a=>Console.WriteLine("Contravariant"));
Action<Dog> actionDog = actionAnimal;
actionDog(aDog);
}