迭代不同类型的列表

时间:2015-03-25 12:57:29

标签: c# foreach interface

当尝试使用不同类型迭代列表时,我遇到了一些不寻常的东西。我在下面有一些示例代码。

我使用两个接口:

interface IViewable
{
    void View();
}

interface IHideable
{
    void Hide();
}

以下课程:

class AwesomeClass : IViewable, IHideable
{
    public void Hide()
    {
        Console.WriteLine("Le hiding.");
    }

    public void View()
    {
        Console.WriteLine("Le toucan has arrived.");
    }
}

class LessAwesomeClass : IViewable
{
    public void View()
    {
        Console.WriteLine("Le arrival.");
    }
}

注意:LessAwesomeClass 继承IHideable

以下是使用这些的示例控制台应用程序:

static void Main(string[] args)
    {
        List<IViewable> viewable = new List<IViewable>();

        viewable.Add(new AwesomeClass());
        viewable.Add(new LessAwesomeClass());

        //This runs fine.
        foreach (IViewable view in viewable)
            view.View();

        //Oh no! InvalidCastException
        foreach (IHideable hidable in viewable)
            hidable.Hide();

        Console.Read();
    }

当尝试遍历类型为IHideable的列表时,它会抛出InvalidCastException。这是有道理的,因为它显然试图将项目转换为IHideable。我理解这一点。

现在问题是应用程序编译。我认为这有点奇怪。

这让我感到很困惑,因为我正在写这个并且在想,“嘿!我可以为IHideable的每个循环做一个,并且过滤掉任何不可能的东西,非常好!哦等待,InvalidCastException。“

所以第一个问题是为什么要编译? 第二个问题,是否有办法在执行foreach循环时过滤掉不是IHideable的所有内容?

无论哪种方式,这样做可能不是一个好主意,它更像是“我想知道这是否有用”。

1 个答案:

答案 0 :(得分:4)

  

为什么要编译?

EricLippert answers it here

  

有没有办法过滤掉IHideable之后的所有内容   做一个foreach循环?

是的,使用OfType扩展方法。

foreach (IHideable hidable in viewable.OfType<IHideable>())
    hidable.Hide();