[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)

Interface looks like this:

public interface IPauseable
	void Pause(bool bPaused);

Not entirely sure why this error is occurring.
Thanks in advance.

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 MBCollectionis’ indeed an IPausable because MB implements IPausable.

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.