Phil
Phil

Reputation: 627

How to use foreach with inherited classes?

I have a base class of Item. The inherited class is Book. So, a book is an item. Fantastic.

Now, I have a method called Take(). It does a foreach on all items.

It's doing...

foreach (Item item in lstItems)

It also gets my Book object, but just the base members.

Of course, I can't get the Book's specific properties from it. Since not all items are books, I don't want to cast item to Book each time.

Is there a common way to get an inherited class in a foreach with C#?

Upvotes: 1

Views: 2177

Answers (2)

quantdev
quantdev

Reputation: 23793

To complete other answers (i.e. there are many ways to cast things), you usually don't have have to use any form of cast when dealing with inheritance. More, the exact goal of inheritance is to deal with polymorphic types.

You are supposed to provide polymorphic methods that acts logically on every class of your hierarchy.

For instance, provide an Execute() method that does nothing in the base class, and which Book properly overrides.

public class Item
{
    public virtual void Execute() {}
}

public class Book : Item
{
    public override void Execute() { Console.WriteLine("I'm a book"); }
}

public class Test
{
    public static void Main()
    {
        List<Item> items = new List<Item> { new Item() , new Item() , new Book(), new Book() };
        foreach(var item in items)
            item.Execute();
    }
}

If this is not suitable for you, then maybe that Book should not inherits from Item in the first place.

Upvotes: 2

user3715766
user3715766

Reputation:

If the list had A's in it (or other things that aren't B or subclasses of B),

then it would simply break with an invalid-cast. You probably want:

foreach(B i in lstItems.OfType<B>()) {...}

in .NET 3.5. (I'm assuming that the lstItems itself will be non-null, btw.)

Upvotes: 5

Related Questions