Dan*_*nny 59 .net c# generics compiler-errors
以下代码为您提供编译器错误,正如您所期望的那样:
List<Banana> aBunchOfBananas = new List<Banana>();
Banana justOneBanana = (Banana)aBunchOfBananas;
Run Code Online (Sandbox Code Playgroud)
但是,在使用时IEnumerable<Banana>,您只会收到运行时错误.
IEnumerable<Banana> aBunchOfBananas = new List<Banana>();
Banana justOneBanana = (Banana)aBunchOfBananas;
Run Code Online (Sandbox Code Playgroud)
为什么C#编译器允许这样做?
Yuc*_*uck 48
我想这是因为它IEnumerable<T>是一个接口,某些实现可以有一个显式的强制转换Banana- 无论多么愚蠢.
另一方面,编译器知道List<T>无法显式地转换为a Banana.
顺便说一下,很好的例子选择!
添加一个例子来澄清.也许我们有一些"可枚举的"应该总是包含最多一个Banana:
public class SingleItemList<T>:Banana, IEnumerable<T> where T:Banana {
public static explicit operator T(SingleItemList<T> enumerable) {
return enumerable.SingleOrDefault();
}
// Others omitted...
}
Run Code Online (Sandbox Code Playgroud)
然后你可以这样做:
IEnumerable<Banana> aBunchOfBananas = new SingleItemList<Banana>();
Banana justOneBanana = (Banana)aBunchOfBananas;
Run Code Online (Sandbox Code Playgroud)
因为它与编写以下内容相同,编译器非常满意:
Banana justOneBanana = aBunchOfBananas.SingleOrDefault();
Run Code Online (Sandbox Code Playgroud)
jas*_*son 29
当你说Y y = (Y)x;这个演员对编译器说:"相信我,无论如何x,在运行时它可以被转换为a Y,所以,就这样做,好吗?"
但是当你说的时候
List<Banana> aBunchOfBananas = new List<Banana>();
Banana justOneBanana = (Banana)aBunchOfBananas;
Run Code Online (Sandbox Code Playgroud)
编译器可以查看每个具体类(Banana和List<Banana>)的定义,并看到没有static explicit operator Banana(List<Banana> bananas)定义(请记住,必须在要转换的类型或要转换的类型中定义显式转换,这是来自规范,第17.9.4节).它在编译时知道你所说的不可能是真的.所以你大吼大叫停止说谎.
但是当你说的时候
IEnumerable<Banana> aBunchOfBananas = new List<Banana>();
Banana justOneBanana = (Banana)aBunchOfBananas;
Run Code Online (Sandbox Code Playgroud)
好吧,现在编译器不知道.很有可能的情况是,无论aBunchOfBananas在运行时发生什么,它的具体类型X都可以定义static explicit operator Banana(X bananas).所以编译器信任你,就像你问的那样.
| 归档时间: |
|
| 查看次数: |
1469 次 |
| 最近记录: |