简体   繁体   中英

Iterating through a list with a different type

I came across something unusual when trying to iterate through lists using a different type. I have some example code below.

I am using two interfaces:

interface IViewable
{
    void View();
}

interface IHideable
{
    void Hide();
}

And the following classes:

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.");
    }
}

Note: LessAwesomeClass does not inherit IHideable

Here is an example console application that uses these:

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();
    }

When attempting to iterate through the list where the type is IHideable , it throws an InvalidCastException. This makes sense, as it's clearly trying to cast the item to IHideable . I understand this.

Now the problem here is that the application compiles . Which I think is a bit odd.

This is what confused me, as I was writing this and was thinking, "Hey! I can do a for each loop for IHideable and filter out anything that isn't IHideable, great! Oh wait, InvalidCastException."

So the first question is why does this compile ? And the second question, is there a way to filter out everything that isn't IHideable when doing a foreach loop?

Either way, it probably isn't a good idea to do this, it was more of a "I wonder if this will work" situation.

why does this compile?

EricLippert answers it here

Is there a way to filter out everything that isn't IHideable when doing a foreach loop?

Yes, use OfType extension method.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM