c#协变和抗变_C# 基础系列--泛型(抗变和协变)

泛型的抗变和协变是在.NET4.0中才增加, 这对之前的接口的一个不错的扩展。抗变和协变是指针对参数和返回值的类型转换。

看了下评论,抗变和协变 在 msdn的翻译是逆变和协变。我先是看C#高级编程第七版的中文版的,所以还是比较习惯抗变和协变。

抗变和协变的在msdn的解释

在 C# 和 Visual Basic 中,协变和逆变允许数组类型、委托类型和泛型类型参数进行隐式引用转换。 协变保留分配兼容性,逆变与之相反。

关键字的传送门:out

通过协变,可以使用与泛型参数指定的派生类型相比,派生程度更大的类型。 这样可以对委托类型和实现变体接口的类进行隐式转换。 引用类型支持协变和逆变,但值类型不支持。

通过逆变,可以使用与泛型参数指定的派生类型相比,派生程度更小的类型。 这样可以对委托类型和实现变体接口的类进行隐式转换。 引用类型支持泛型类型参数中的协变和逆变,但值类型不支持。

在.NET中 参数类型是协变,返回值是抗变。

不要废话了,先定义两个我们例子用的实体类---基类  RectangleBase  派生类--Rectangle

public class RectangleBase

{

public int ID { get; set; }

}

public class Rectangle : RectangleBase

{

public string Name { get; set; }

}

如果有个方法 public void Display(RectangleBase  r)  我们传入一个 Rectangle 的实体,那么就是一个参数类型的协变

如果有个方法public RectangleBase   GetRectangle()  我们这里 RectangleBase b = GetRectangle() 那么这就是方法返回类型的抗变。

在4.0之前,泛型接口是不拥有想上面类的便利性。很幸运,微软在 4.0对泛型接口扩展这写!

协变

如果泛型接口中有关键字 out的,那个这个泛型接口就是协变。这个就定义了这个接口只能返回类型只能是T。

我们先定义一个接口

public interface IIndex

{

T this[int index] { get; }

int Count { get; }

}

我们的实现类:

public class RectangleCollection : IIndex

{

List list = new List();

public Rectangle this[int index]

{

get

{

if (index < 0 || index > Count)

throw new ArgumentOutOfRangeException("index");

return list[index];

}

}

public int Count

{

get { return list.Count; }

}

public void  Add(Rectangle value)

{

list.Add(value);

}

}

然后我们在控制台是这样:

var list = new RectangleCollection();

list.Add(new Rectangle { ID = 1, Name = "111" });

list.Add(new Rectangle { ID = 2, Name = "222" });

list.Add(new Rectangle { ID = 3, Name = "33" });

IIndex Bas = list;

for (int i = 0; i < Bas.Count; i++)

{

Console.WriteLine(Bas[i].ID);

}

Console.Read();

协变很简单吧。。。如果你吧关键字out 去掉后,编译器很快就会个告诉你  IIndex Bas = list; 错误。因为你没有告诉他 这个T是可以变的

抗变

如果泛型接口有关键字in ,那么表示这个泛型接口是可以抗变的。这样,接口也只能把泛型类型T用作方法的输入。

定义泛型抗变的 接口

public interface IDisplay(in T)

{

void Show(T item);

}

抗变类:

public class RectangleDisplay: IDisplay

{

public void Show(RectangBase item)

{

Console.WrileLine(item.ID);

}

}

这篇写的不是很好,因为我自己也不是吃的很透,今天在朋友的稍稍点拨下,算是有点 理解这个了。第一次接触这个东西到现在又一年多了,今天才理解点,惭愧惭愧。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值