Mike Eason
Mike Eason

Reputation: 9713

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.

Upvotes: 0

Views: 154

Answers (1)

Sriram Sakthivel
Sriram Sakthivel

Reputation: 73452

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

Upvotes: 4

Related Questions