- 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? :/
Your answer