You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rx.NET中Scan无resultSelector重载原因及自定义实现方法

设计原因

Aggregate和Scan的核心行为差异决定了API设计的区别:

  • Aggregate仅会在源序列完成时,输出唯一的最终累加结果,resultSelector只需要执行一次,用来把最终累加值转换为目标类型,符合Aggregate单次输出的语义,也和LINQ原生的Aggregate重载设计保持一致。
  • Scan是每收到一个源元素就输出当前的累加结果,属于连续多输出的操作符。Rx.NET团队没有提供带resultSelector的重载,是因为直接调用Scan(seed, accumulator).Select(resultSelector)就可以完全实现相同效果,不需要额外增加API的维护成本和理解成本。
自定义Scan操作符实现

你要求的签名可以通过封装原生操作符快速实现,这种方式复用了Rx.NET内置的线程安全、生命周期管理、错误处理逻辑,是最稳妥的实现方案:

using System;
using System.Reactive.Linq;

public static class ObservableExtensions
{
    public static IObservable<TResult> Scan<TSource, TAccumulate, TResult>(
        this IObservable<TSource> source,
        TAccumulate seed,
        Func<TAccumulate, TSource, TAccumulate> accumulator,
        Func<TAccumulate, TResult> resultSelector)
    {
        if (source == null) throw new ArgumentNullException(nameof(source));
        if (accumulator == null) throw new ArgumentNullException(nameof(accumulator));
        if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector));

        return source.Scan(seed, accumulator).Select(resultSelector);
    }
}

使用示例

以下代码演示了每次接收数字后输出累加和的两倍值:

// 生成1-5的序列
var numberSource = Observable.Range(1, 5);

numberSource.Scan(
    seed: 0,
    accumulator: (sum, current) => sum + current,
    resultSelector: total => $"当前累加和的两倍为:{total * 2}"
)
.Subscribe(Console.WriteLine);

运行输出如下:

当前累加和的两倍为:2
当前累加和的两倍为:6
当前累加和的两倍为:12
当前累加和的两倍为:20
当前累加和的两倍为:30

内容的提问来源于stack exchange,提问作者jack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 10:36:03