2017-12-17 7 views
3

ストリーム/観測可能なオブジェクト内の特定のタイプのオブジェクトをフィルタ処理するヘルパーを作成しています。これは、要旨次のとおりです。IObservable、ランタイム例外の無効なキャスト

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); 
} 

このように使用:

this.When<OpenDoorAction>() 
    .Subscribe(a => Debug.Log(a)); 

次の例外は、上記マークされた行のためにスローされます。

InvalidCastExceptionが:指定されたキャストは有効ではありません。

私はIGameActionと実装者のいずれか、両方のクラスを使用しようとしました(例:OpenDoorAction)。なぜ私はIObservable<T>へのキャストが必要なのか理解できませんが、コンパイラはそれがなければ、IObservable<IGameAction>からIObservable<T>への暗黙のキャストはないと言います。 SubjectIObservableを実装しています。

FWIWは、このIObservable<IGameAction>、あなたが制約を指定したにも関わらずIObservable<T>の間には直接的なキャストがありませんので、これはUniRx

答えて

4

を使用してUnity3Dです。

代わりに、ストリーム内の個々の項目を再キャストする必要があります。

return this.Actions.Where(action => action is T).Cast<T>();

そして、あなたの戻り値が正しいタイプのIObservableになります。


mjwillsはコメントで指摘するように、IObservable<T>.OfType<T2>のヘルパー関数は、基本的にはちょうどあなたのための場所とキャストをしている、存在しています。

+1

'返すthis.Actions.OfType ();' – mjwills

+0

それは確かにすべきです!それは基本的にちょうどあなたのために 'Where'と' Cast'を行います。 – Clint

+1

ああ、それは意味があります!ソースの種類も指定しなければならなかったので、 'this.Actions.OfType ()'です。不思議なことに、 '.Cast 'は '.Select(a =>(T)a)'の効果を発揮します。これは問題の「解決策」です。ありがとう! – altschuler

関連する問題