不合法的IObservable转换,运行时异常。

3
我正在创建一个帮助程序来过滤流/可观察对象中特定类型的对象。以下是要点:

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

以下代码中标记的行引发了以下异常:
无效转换异常:指定的转换无效。
我尝试使用 IGameAction 和其实现者(例如 OpenDoorAction)的类,但是我不明白为什么需要强制转换为 IObservable<T>,如果没有它,编译器会说从 IObservable<IGameAction>IObservable<T> 没有隐式转换。 Subject 实现了 IObservable
顺便说一下,这是在使用 UniRx 的 Unity3D 中。
1个回答

4
这是因为IObservable<IGameAction>IObservable<T>之间没有直接的转换,即使您已经指定了约束条件。相反,您应该重新转换流中的单个项:return this.Actions.Where(action => action is T).Cast<T>();然后您的返回值将是正确类型的IObservable。
如评论中的mjwills所指出的那样,IObservable<T>.OfType<T2>的帮助函数存在,它基本上只为您执行where和cast。

当然应该!这基本上只是为您执行“Where”和“Cast”。 - Clint
1
啊哈,那就有意思了!我必须指定源类型,所以是 this.Actions.OfType<IGameAction, T>()。对于好奇的人来说,.Cast<T> 的作用类似于 .Select(a => (T)a),这也是解决问题的一种“方案”。谢谢! - altschuler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接