Covariant(协变) vs Contravariant(逆变)

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);
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值