c# - 如何获得 IObservable 的最后已知值?

标签 c# system.reactive rx.net

假设我正在使用 Rx.Net 构建一个图像编辑器。用户可以使用鼠标操作 Canvas 。应用的操作取决于当前选择的工具。例如,可能有一个“绘图”工具和一个“删除”工具。一次只能选择一个工具。

我有三个流;一个用于鼠标事件;一个用于通过单击鼠标发出的命令;另一个用于工具选择:

IObservable<ITool> toolSelection;
IObservalbe<MouseState> mouse;
IObservable<ICommand> commands;

commands 流依赖于其他两个:当用户单击鼠标时发出命令,生成的命令取决于最后选择的工具。请注意,当用户更改工具时,不应 发出命令,只有当他们单击鼠标时才发出。

现在,我可以将最后选择的工具存储在这样的变量中:

var selectedTool = defaultTool;
toolSelection.Subscribe(x => selectedTool = x);

我可以使用 selectedTool 构建 commands 流:

var commands = mouse.Select(x => selectedTool.CreateCommand(x));

但是,这看起来不像是“响应式(Reactive)”的做事方式。我可以使用流组合实现同样的逻辑吗?

我查看了 CombineLatest,但它会导致在用户切换工具时生成不需要的事件。我只希望在用户单击时发出命令。

最佳答案

听起来你需要.Switch() .

试试这段代码:

IObservable<ICommand> commands =
    toolSelection
        .Select(t => mouse.Select(m => t.CreateCommand(m)))
        .Switch();

扩展方法.Switch()在这种情况下,采用 IObservable<IObservable<ICommand>>并将其变成 IObservable<ICommand>通过获取外部可观察对象产生的最新可观察对象,仅从中产生值并处理之前的值。

或者,用更多的英语术语来说,每当用户点击一个新工具时,您都会在一个漂亮的查询中获得仅使用最新工具构建的鼠标命令流。

关于c# - 如何获得 IObservable 的最后已知值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38228516/

相关文章:

c# - 如何使用 Reactive 扩展实现 filewatcher

c# - 在 SignalR hub 中创建 Rx.NET Observable

.net - RxJS/Rx.Net 可观察订阅与事件 - 性能/线程

c# - 即时生成自签名证书

c# - 如何将 IList<T> 映射到位图?

c# - 在 XAML 中使用枚举值

c# - 如何将 IObservable<IObservable<T>> 转换为 IObservable<IEnumerable<T>>?

c# - 某处有 Ix.NET (System.Interactive) 的示例吗?

c# - 奇怪的 Rx+CancellationToken 问题 : sometimes the registered callback does not complete

c# - 带有 Entity Framework 的 MVC 3 和编辑多个对象导致 "referential integrity constraint violation"