为什么订阅从集合中获取的 IObservables 不起作用(以及如何处理)

Why subscriptions to IObservables taken from a Collection don't work (and what to do about it)

我的目标是从源 observable 创建一堆 observable,这样我就可以单独订阅它们。

当我手动执行此操作(即手动创建每个子源)时,事情按预期工作:添加到原始源的值充分传播到子源。

但是当我在循环中创建它们并将它们添加到 List<IObservable<T>> 时,对从该列表中获取的元素的订阅似乎不起作用:

class Program
{
    static void Main(string[] args)
    {
        // using Subject for the sake of example
        var source = new Subject<int>(); 


        // manually creating each subSource
        var source0 = source.Where((t, i) => i % 3 == 0);
        var source1 = source.Where((t, i) => i % 3 == 1);
        var source2 = source.Where((t, i) => i % 3 == 2);


        // creating a List of subsources
        List<IObservable<int>> sources = new List<IObservable<int>>();

        int count = 3;

        for (int i = 0; i < count; i++)
        {
            sources.Add(source.Where((v, ix) => ix % 3 == i));
        }


        // subscribing to one subSource from each group
        source0.Subscribe(Console.WriteLine); // this works
        sources[1].Subscribe(Console.WriteLine); // this doesn't

        // feeding data
        Observable.Range(0, 20).Subscribe(source);

        Console.ReadKey();
    }
}
for (int i = 0; i < count; i++)
{
    **var j = i;**
    sources.Add(source.Where((v, ix) => ix % 3 == j));
}

闭包。

您的 Where 子句的谓词引用循环变量 i.

但是,在从 source 发布值时测试谓词 - 而不是在迭代循环时。到那时,i 已达到最终值 3

要解决此问题,请在循环内创建一个新变量来存储 i 的当前值,并在您的 Where 谓词中引用它:

for (int i = 0; i < count; i++)
{
    var j = i;
    sources.Add(source.Where((v, ix) => ix % 3 == j)); // note use of j here
}