其他分享
首页 > 其他分享> > 我为什么可以在不相关的接口列表的foreach中使用(几乎)任何类型?

我为什么可以在不相关的接口列表的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