IList的< T>和List< T>用接口转换 [英] IList<T> and List<T> Conversions with Interfaces

查看:219
本文介绍了IList的< T>和List< T>用接口转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我大致明白接口,继承和多态,但有一件事我感到困惑。



在这个例子中,工具 IAnimal 当然的列表工具的IList

  IList的< IAnimal>猫=新的List< CAT和GT;(); 



但它会产生一个编译错误的(无法隐式转换类型...)。同时,如果我使用asbtract超[动物]认为猫从继承将不起作用。但是,如果我替换 IAnimal



 的IList<猫> ;猫=新的List< CAT和GT;(); 



它编译的罚款。



在我一点,因为工具 IAnimal ,第一个例子中的的可以接受的,让我们回到一个接口列表和包含的类型两者。



任何人都可以解释为什么它是不是有效?我敢肯定有一个合乎逻辑的解释。


解决方案

有一个合理的解释,而这个精确的问题是每天都问差不多。在计算器上



假设这是合法的:

 的IList< IAnimal> ;猫=新的List< CAT和GT;(); 



这是什么被合法吗?



<$停止p $ p> cats.Add(新长颈鹿());



没有。 猫是动物的列表,和一个长颈鹿是动物,并且因此可以长颈鹿添加猫的列表。



显然未类型安全。



在C#4我们增加了一个功能,让你可以做,如果元数据注解让编译器证明它是类型安全的。在C#4你​​可以这样做:

 的IEnumerable< IAnimal>猫=新的List< CAT和GT;(); 

由于的IEnumerable< IAnimal> 无添加方法,所以没有办法违反类型安全。



请参阅我们如何设计在C#4此功能的更多详细信息我的系列文章。



的http://博客。 msdn.com/b/ericlippert/archive/tags/covariance+and+contravariance/default.aspx



(开始从底部。)

I generally understand interfaces, inheritance and polymorphism, but one thing has me puzzled.

In this example, Cat implements IAnimal and of course List implements IList:

IList<IAnimal> cats = new List<Cat>();

but it generates a compilation error (Cannot implicitly convert type...). It also won't work if I use an asbtract superclass [Animal] that Cat inherits from. However, If I replace IAnimal with Cat:

IList<Cat> cats = new List<Cat>();

it compiles fine.

In my mind, because Cat implements IAnimal, the first example should be acceptable, allowing us to return an interface for both the list and the contained type.

Can anyone explain why it isn't valid? I'm sure there's a logical explanation.

解决方案

There is a logical explanation, and this exact question is asked pretty much every day on StackOverflow.

Suppose this was legal:

IList<IAnimal> cats = new List<Cat>(); 

What stops this from being legal?

cats.Add(new Giraffe());

Nothing. "cats" is a list of animals, and a giraffe is an animal, and therefore you can add a giraffe to a list of cats.

Clearly that is not typesafe.

In C# 4 we added a feature whereby you can do that if the metadata annotations allow the compiler to prove that it is typesafe. In C# 4 you can do this:

IEnumerable<IAnimal> cats = new List<Cat>(); 

because IEnumerable<IAnimal> has no Add method, so there is no way to violate type safety.

See my series of articles on how we designed this feature in C# 4 for more details.

http://blogs.msdn.com/b/ericlippert/archive/tags/covariance+and+contravariance/default.aspx

(Start from the bottom.)

这篇关于IList的&LT; T&GT;和List&LT; T&GT;用接口转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆