Reputation: 9713
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
Reputation: 73452
why does this compile?
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