- Home /
[C#] Calling Interface from Array of MonoBehaviour
Cannot cast from source to destination type.
Occurrence at second line of code sample underneath. -> foreach(IPauseable I in MB) <-
MonoBehaviour[] MB = GameObject.FindObjectsOfType(typeof(MonoBehaviour)) as MonoBehaviour[];
foreach(IPauseable I in MB)
{
I.Pause(true);
}
Interface looks like this:
public interface IPauseable
{
void Pause(bool bPaused);
}
Not entirely sure why this error is occurring. Thanks in advance.
Answer by ArkaneX · Sep 15, 2013 at 09:18 PM
The problem is you're retrieving all the active MonoBehaviours in the scene, but I bet only some of them implement IPauseable. When foreach encounters one which does not implement this interface, an exception is thrown.
To achieve what you want, I suggest selecting valid MonoBehaviours using LINQ. Change your foreach line to:
foreach (IPauseable I in MB.Where(x => x is IPauseable))
Where method is LINQ extension from System.Linq namespace, so this requires adding
using System.Linq;
at the top of your script.
If you don't want to use the LINQ namespace, an alternative to using LINQ is the following:
foreach($$anonymous$$onoBehavior I in $$anonymous$$B){
if(I is IPauseable){
IPauseable temp = (IPauseable)I;
//possibly you might have to have cast to System.Object first...
//(IPauseable)((System.Object)I)
//do whatever
}
}
Answer by vexe · Sep 15, 2013 at 03:22 AM
Not sure why you would expect it to work. See here.
A "Cannot cast from source to destination type" is well... an invalid-cast error. In other words, you're trying to reference an incorrect type into a type-restricted variable.
You're saying foreach (IPauseable I in MB)
- it's like saying foreach (int i in myStrings)
The general syntax of a foreach:
foreach (Type t in TypeCollection)
What comes after the in
should either be a collection of '`Type`'s, like:
foreach (string s in myStrings)
Or, if you got inheritance going on, let's say you have an Enemies
array, and you had a Zombie
type of enemy, you could say:
foreach (Zombie z in Enemies)
This is valid because a Zombie 'is an' Enemy
.
Notice that interfaces can inherit from other interfaces, but not other classes (you can't have your IPauseable
inherit MonoBehaviour
)
So you're iterating over something that isn't an IPausable
. How can you fix this? - You could create a separate class that inherits from MonoBehaviour
and implements your IPausable
.
class MB : MonoBehaviour, IPausable { // goodies... }
Now you can do:
foreach (IPausable p in MBCollection)
// do stuff
Where MBCollection
is a sequence of MB
(array, list, etc) This is now valid because every element of MBCollection
'`is`' indeed an IPausable
because MB
implements IPausable
.
[2]: http://msdn.microsoft.com/en-us/library/ttw7t8t6%28v=vs.90%29.aspx
I still do not understand. I have the array of $$anonymous$$onobehaviours from. $$anonymous$$onoBehaviour[] $$anonymous$$B = GameObject.FindObjectsOfType(typeof($$anonymous$$onoBehaviour)) as $$anonymous$$onoBehaviour[];
And i'm looping through them for the ones which inherit IPauseable. Won't what your doing give a cast error too? :/