Mike John
Mike John

Reputation: 818

foreach in a list [C#]

MonoBehavior[] list; // This is from Unity3d but think of it as Object, 
                     // all classes inherit from it.

The list is filled with lots of things, some are Alpha, from the class Alpha, and others are from other classes.

foreach(Alpha a in list) // Alpha is a script. 
  a.doSomething();

I was under the assumption that my foreach would work this way: Foreach Alpha script found in list do something, ignore every other component.

This is a casting problem, I think. Please help me understand casting/polymorphism better.

I get this error during execution: Cannot cast from source type to destination type

Upvotes: 6

Views: 12706

Answers (7)

user2085599
user2085599

Reputation:

This is how I would do it and I know for sure it would compile in Unity3d. OfType is not in Unity by the way, TypeOf is but as taras.roshko said using is is better.

MonoBehavior[] list;

foreach(MonoBehavior current in list) // Search the whole list for MonoBehaviors.
    if (current  is Alpha)            // Check if current is an Alpha type.
        current.doSomething();        // current is a valid Alpha type script.

The foreach will try to convert all the elements on the list and since Alpha is a MonoBehavior but MonoBehavior is not Alpha you can't run it correctly. So you check if current is an Alpha and then if it is use it however you like.

Upvotes: 2

TalentTuner
TalentTuner

Reputation: 17556

If your list contains list of base type and you are just taking each element and try to think it is of type Alpha than it is illegal try with below

foreach(Unity3d a in list) // Alpha is a script. 
     a.doSomething();

assuming doSomething() is defind in Unity3d

Upvotes: 0

Roman Gruber
Roman Gruber

Reputation: 1391

You're going at polymorphism the wrong way around: While Alpha is a derived type, not all other objects in your list of type MonoBehavior are. Hence some will fail the implicit type cast that foreach is doing. You could use the "OfType()" extension if it is available in your environment:

foreach(Alpha a in list.OfType<Alpha>())

Upvotes: 14

If you want the loop to only operate on Alpha types, you need to rewrite as the following:

foreach (var item in list)
{
  if (item is Alpha)
  {
    ((Alpha) item).doSomething();
  }
}

edit: Maarten's answer uses LINQ, which is more concise, so I'd recommend that one.

Upvotes: 2

Maarten
Maarten

Reputation: 22955

You can try something like:

foreach(Alpha a in list.Where(x => x is Alpha)) // Alpha is a script. 
  a.doSomething();

Upvotes: 13

illegal-immigrant
illegal-immigrant

Reputation: 8254

use OfType to iterate over elements of specified type only

Upvotes: 2

greenkode
greenkode

Reputation: 3996

your foreach statement will try to cast every object in there to Alpha. If they have a common superclass, you can use that, otherwise use the Object class.

Upvotes: 0

Related Questions