Kiloku
Kiloku

Reputation: 553

How to use a Foreach in a base type list in C#

I have a list of type GameObject called "Within" in each of my Tiles.

List<GameObject> Within = new List<GameObject>();

GameObject has derived classes of types Bee, Flower and Tree.

I am doing a foreach that should detect all bees inside the list and select or unselect them.

foreach (Bee bee in Tile.Within)
{
    bee.selected = !bee.selected;
}

Problem is, when I do that, if the list has an object of type Flower or Tree, I get an Exception:

"Unable to cast object of type 'WindowsGame2.Flower' to type 'WindowsGame2.Bee'."

I thought that the foreach would ignore all objects that don't fit in the description when we call it, but it doesn't... How can I get it to work?

Upvotes: 3

Views: 304

Answers (5)

jv42
jv42

Reputation: 8583

foreach doesn't work that way. It will just 'cast' the object to the requested type.

So you need to either filter beforehand (which might create garbage, if you're on Xbox360, this might be an issue), or filter in your loop.

There are several ways to do that, revolving around the use of either as or is or both. For instance:

foreach (GameObject gameObj in Tile.Within) 
{
    if (gameObj is Bee)
    {
        Bee bee = (Bee)gameObj;
        bee.selected = !bee.selected; 
    }
} 

Upvotes: 1

JiB&#233;Doublev&#233;
JiB&#233;Doublev&#233;

Reputation: 4269

On each iteration you should check the type of the current item. If it is a Bee cast the result and do your work.

foreach (var item in Tile.Within)
{
    if (item is Bee)
    {
        ((Bee)item).Selected = !((Bee)item).Selected;
    }
}

Upvotes: 0

Azodious
Azodious

Reputation: 13872

foreach can be modified as follows:

foreach (GameObject gameObj in Tile.Within) 
{
    Bee bee = gameObj as Bee;
    if(bee != null)
    {
        bee.selected = !bee.selected; 
    }
} 

Upvotes: 2

Marc
Marc

Reputation: 6771

Are you able to use LINQ in your project?

foreach (Bee bee in Tile.Within.Where(o=>o is Bee))
{
    bee.selected = !bee.selected;
}

Upvotes: 1

&#216;yvind Br&#229;then
&#216;yvind Br&#229;then

Reputation: 60694

What about filtering using LINQ inside the foreach?

foreach (Bee bee in Tile.Within.OfType<Bee>())
{
    bee.selected = !bee.selected;
}

That will only select the Bee's and no flowers or trees.

Upvotes: 8

Related Questions