Reputation: 818
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
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
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
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
Reputation: 29939
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
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
Reputation: 8254
use OfType to iterate over elements of specified type only
Upvotes: 2
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