我为什么可以在不相关的接口列表的foreach中使用(几乎)任何类型?
作者:互联网
在下面的示例中,通过第一个foreach,我确定它会引发编译错误,但是它们可以正常运行.仅在运行时抛出无效的强制转换异常(如您所料)时,才会发生问题:
public interface IState
{
int Id { get; }
string Description { get; }
}
public class Dog
{
public string Name { get; set; }
public string Breed { get; set; }
}
public class Cat
{
public string Name { get; set; }
public string Breed { get; set; }
}
public void Foo()
{
IEnumerable<IState> states = new List<IState>();
foreach (Dog dog in states) { } // Does not break in the compiler
IEnumerable<Cat> cats = new List<Cat>();
foreach (Dog dog in cats) { } // Obviously breaks in compiler
}
为什么这会通过编译器? Dogis与IState完全无关,如果我尝试遍历Cat列表,则编译器显然会捕获它.
解决方法:
编译器正在将类型转换从元素类型隐式转换为您在foreach语句中指定的类型.
因此,如果您有IEnumerable< Foo>并将其用作:
foreach (Bar bar in foos)
然后将插入从Foo到Bar的演员表.当且仅当该强制转换通常有效时,此函数才会编译.
从猫到狗的投射是无效的,因为它们是不相关的类型.猫参考绝对不能作为狗参考有效.
如果从IState强制转换为Dog是有效的,因为它可能是有效的:
public class DogState : Dog, IState
{
public int Id => 5;
public string Description => "Dog state!";
}
IState state = new DogState();
Dog dog = (Dog) state; // Won't throw
在您的收藏示例中:
IEnumerable<IState> states = new List<IState> { new DogState() };
foreach (Dog dog in states)
{
Console.WriteLine("I've got a dog state!");
}
标签:c-4-0,compiler-errors,c 来源: https://codeday.me/bug/20191108/2009997.html