为什么这种隐式转换不会导致编译时错误?
Why does this implicit cast not result in compile-time error?
只是想了解 C#。仅考虑以下简化示例。
void Main()
{
IList<IAnimal> animals = new List<IAnimal>
{
new Chicken(),
new Cow(),
};
// Shouldn't this line result in a compile-time error?
foreach (Chicken element in animals)
{
}
}
public interface IAnimal
{
}
public class Cow : IAnimal
{
}
public class Chicken : IAnimal
{
}
虽然第一次迭代成功,但第二次没有。老实说,我预计这会在编译时失败。有谁知道为什么它只在运行时失败?
因为 foreach
语句在 C# Language Specification 中定义有一个(隐藏的)显式转换:
The above steps, if successful, unambiguously produce a collection type C, enumerator type E and element type T. A foreach statement of the form
foreach (V v in x) embedded-statement
is then expanded to:
{
E e = ((C)(x)).GetEnumerator();
try {
while (e.MoveNext()) {
V v = (V)(T)e.Current;
embedded-statement
}
}
finally {
… // Dispose e
}
}
(注意 (V)(T)e.Current
,"explicit" 转换为类型 V
)
不幸的是,它是这样定义的,因为这是您在 C# 1 中真正需要的(在泛型之前,您希望在 foreach
是 object
) 的集合,现在,为了向后兼容,它不能更改。
只是想了解 C#。仅考虑以下简化示例。
void Main()
{
IList<IAnimal> animals = new List<IAnimal>
{
new Chicken(),
new Cow(),
};
// Shouldn't this line result in a compile-time error?
foreach (Chicken element in animals)
{
}
}
public interface IAnimal
{
}
public class Cow : IAnimal
{
}
public class Chicken : IAnimal
{
}
虽然第一次迭代成功,但第二次没有。老实说,我预计这会在编译时失败。有谁知道为什么它只在运行时失败?
因为 foreach
语句在 C# Language Specification 中定义有一个(隐藏的)显式转换:
The above steps, if successful, unambiguously produce a collection type C, enumerator type E and element type T. A foreach statement of the form
foreach (V v in x) embedded-statement
is then expanded to:
{
E e = ((C)(x)).GetEnumerator();
try {
while (e.MoveNext()) {
V v = (V)(T)e.Current;
embedded-statement
}
}
finally {
… // Dispose e
}
}
(注意 (V)(T)e.Current
,"explicit" 转换为类型 V
)
不幸的是,它是这样定义的,因为这是您在 C# 1 中真正需要的(在泛型之前,您希望在 foreach
是 object
) 的集合,现在,为了向后兼容,它不能更改。