C# CombineLatest是否保持了观测值的顺序?

C# CombineLatest是否保持了观测值的顺序?,c#,.net,system.reactive,reactive-programming,C#,.net,System.reactive,Reactive Programming,我对以下重载感兴趣: public static IObservable<IList<TSource>> CombineLatest<TSource>(this params IObservable<TSource>[] sources); public static IObservable<IList<TSource>> CombineLatest<TSource>(this IEnumerable<IO

我对以下重载感兴趣:

public static IObservable<IList<TSource>> CombineLatest<TSource>(this params IObservable<TSource>[] sources);
public static IObservable<IList<TSource>> CombineLatest<TSource>(this IEnumerable<IObservable<TSource>> sources);
文件规定:

包含最新源元素的列表

以及:

包含源的最新元素列表的可观察序列


但实际上没有提到任何关于顺序的内容。

combinelateest
在有一个元素被推送到所有流时首先激发

之后,每当新元素被推送到任何流时,它都会激发

因此,如果您“组合”两个流,结果列表中始终包含两个元素,据我所知,可以保证顺序与您在
combinelateest
参数中为流指定的顺序相同


您可以使用大理石图可视化Rx操作员。是用于
CombineTest

的,顺序保持不变

当您查看时,所有这些都归结为
System.Reactive.Linq.CombineTest

您可以在那里发现,为每个输入可观察对象创建了一个索引观察者(其中索引是输入中的顺序):

for(int i=0;i
生成的元素如下所示:

private void OnNext(int index, TSource value)
{
    lock (_gate)
    {
        _values[index] = value;
        _hasValue[index] = true;

        if (_hasValueAll || (_hasValueAll = _hasValue.All(Stubs<bool>.I)))
        {
                /* snip */
                res = _parent._resultSelector(new ReadOnlyCollection<TSource>(_values));
                /* snip */

            _observer.OnNext(res);
        }
        /* snip */
    }
}
private void OnNext(int索引,TSource值)
{
锁(门)
{
_数值[指数]=数值;
_hasValue[索引]=真;
如果(_hasValueAll | |(_hasValueAll=_hasValue.All(Stubs.I)))
{
/*剪断*/
res=_parent._resultSelector(新的只读集合(_值));
/*剪断*/
_OnNext观察员(res);
}
/*剪断*/
}
}

我感兴趣的重载的
\u resultSelector
只是一个
可枚举的.ToList()
。因此,输出列表中的顺序将与输入列表中的顺序相同。

您是否有证据证明该顺序确实得到了保证?比如一份文档或源代码?我最初的测试表明顺序确实是守恒的,但这很难得出结论。如果你不知道结果列表中的哪个流是哪个流,那么整个操作符的意义是什么?如果你说“据我所知”,那么你就没有回答这个问题。你需要对此有把握。为此,我可以推荐源代码,同样是“我能看到”(抱歉,但不会100%地陈述任何内容),它不会出问题:
for (int i = 0; i < N; i++)
{
    var j = i;

    var d = new SingleAssignmentDisposable();
    _subscriptions[j] = d;

    var o = new O(this, j);
    d.Disposable = srcs[j].SubscribeSafe(o);
}
private void OnNext(int index, TSource value)
{
    lock (_gate)
    {
        _values[index] = value;
        _hasValue[index] = true;

        if (_hasValueAll || (_hasValueAll = _hasValue.All(Stubs<bool>.I)))
        {
                /* snip */
                res = _parent._resultSelector(new ReadOnlyCollection<TSource>(_values));
                /* snip */

            _observer.OnNext(res);
        }
        /* snip */
    }
}