2017-12-17 15 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