I'm creating a helper to filter specific types of objects in a stream/observable. This is the gist:
public interface IGameAction { }
// Example action
public struct OpenDoorAction : IGameAction { }
// In Store.cs
public Subject<IGameAction> Actions;
public IObservable<T> When<T>() where T : IGameAction
{
// Exception here
return (IObservable<T>)this.Actions.Where(action => action is T);
}
When used like this:
this.When<OpenDoorAction>()
.Subscribe(a => Debug.Log(a));
The following exception is thrown for the line marked above:
InvalidCastException: Specified cast is not valid.
I have tried using classes for either and both of IGameAction
and the implementors (eg. OpenDoorAction
). I don't understand why I need the cast to IObservable<T>
, but without it the compiler says there is no implicit cast from IObservable<IGameAction>
to IObservable<T>
. Subject
implements IObservable
.
FWIW this is in Unity3D using UniRx
This is because there's no direct cast between IObservable<IGameAction>
and the IObservable<T>
even though you've specified the constraint.
You should instead re-cast the individual items in the stream:
return this.Actions.Where(action => action is T).Cast<T>();
And your return value will then be an IObservable of the correct type.
As mjwills
points out in the comments, a helper function of IObservable<T>.OfType<T2>
exists, which basically just does the where and cast for you.