C#协变和逆变
2021-03-11 11:28
标签:guid each for mamicode 接口 guide nim ros 代码 本篇博客所讲的是C#泛型中的协变和逆变。 首先讲协变: 要把泛型参数定义为协变,可在类型定义中使用out关键字,例如: 相信这个方法,大伙都知道,这个是C#中内置的一个IEnumerable 假定A可以转化为B,如果X可以转为为B,那么称X有一个协变类型参数。 比如这段代码,它能不能执行呢?能的,执行结果如图: 如果我把IEnumerable 根据上面的例子,我们知道C#中Object是最底层的基类,那么string类型是继承object类型的,通过协变IEnumerable C#中有内置的IEnumerable } } 首先定义一个抽象的动物,然后定义一个协变接口,定义一个具体的动物实现抽象方法。 然后定义个一只猫,一只狗。 当具体动物是一只猫的时候,执行方法。 通过手写了一个例子,其实能够发现这个东西还是蛮好用的,但是不是很好理解,需要多去敲代码,才能体会到其中的奥妙。 协变的好处是能够很好的解决复用性的问题。协变仅仅对引用转换有效,对装箱是无效的。 协变在接口(interface)中是比较常见的,但是这个东西需要跟方法中的out参数是要做区分的,方法中的out参数是不支持协变的,这是CLR的限制。 其实这个也还能叫抗变,我看了《C#入门经典第七版》是叫抗变的,目前官方文档的叫法是逆变(https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/concepts/covariance-contravariance/),《C#图解教程》中泛型那一章也是叫逆变的,所有标题就叫逆变好了。 通过协变我们知道,假定A可以转化为B,如果X可以转为为B,那么称X有一个协变类型参数。协变正好相反,即,从X转换为X,它仅在类型参数出现在输入位置上,并且用in修饰符才能行。 下面上例子。 把out修饰符换成in修饰符。 执行代码。 通过上面的协变,再来看这个逆变,其实就是倒过来的,我在实际学习中是也是跟博客一样先学习的协变再学逆变,学逆变的时候感觉这个东西还是蛮通透的。 在c#中也是内置了一些逆变interface的,例如:IComparer c#中的协变和逆变,都是基于泛型,所以例如泛型委托,也是会用到协变和逆变的,这个如果以后写委托的博客的时候再去写一下与之相关的。 写这种纯C#的知识博客,比写记录bug类多了,得看书,查资料。 C#协变和逆变 标签:guid each for mamicode 接口 guide nim ros 代码 原文地址:https://www.cnblogs.com/aqgy12138/p/12636735.html协变
public interface IEnumerableout T> : IEnumerable
{
IEnumerator
{
IEnumerablestring> str = new Liststring> { "Zero", "One", "Two" };
IEnumerableobject> obj = str;
foreach (var item in obj)
{
Console.WriteLine(item);
}
}
public class Cat : Animal
{ ///
ConceteAnimal
逆变
///
ConceteAnimal animal = new ConceteAnimal();
animal.Name(new Animal { Name = "狗" });
IAnimal