如何有效地 select 一个可观察集合中的范围到另一个可观察集合

How to efficiently select a range in an observable collection into another observable collection

类似(伪代码)

ObservableCollection<TheClass> ob1 = new ObservableCollection<TheClass>();
ob1.Add(...);
ob1.Add(...); 
ob1.Add(...);
ob1.Add(...); 
ObservableCollection<TheClass> ob2;
ob2 = ob1.Range(0, 2);

考虑到这两个集合都可能包含大量数据。

谢谢

ObservableCollection 不支持 AddRange 方法。您可以通过编写 扩展方法 或创建一个派生自 ObservableCollection 的新 class 来扩展 ObservableCollection class 的功能] class。例如:

public class ObservableRangeCollection<T> : ObservableCollection<T>
{
    public void AddRange(IEnumerable<T> collection)
    {
        var enumerable = collection as T[] ?? collection.ToArray();
        foreach (var item in enumerable)
        {
            Items.Add(item);
        }
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, enumerable.ToList()));
    }
}

然后你可以为 ob2 创建一个 ObservableRangeCollection 而不是 ObservableCollection 的实例并使用 AddRange 并通过使用 SkipTake 像这样:

ObservableRangeCollection<TheClass> ob2 = new ObservableRangeCollection<TheClass>();
ob2.AddRange(ob1.Take(3));//Returns 3 number of contiguous elements from the start 
// Or to  grab a Range between 2 and 5
ob2.AddRange(ob1.Skip(2).Take(3)) 
ObservableCollection<TheClass> ob1 = new ObservableCollection<TheClass>();
ob1.Add(...);
ob1.Add(...); 
ob1.Add(...);
ob1.Add(...); 
ObservableCollection<TheClass> ob2;

// ob2 = ob1.Range(0, 2);
ob2 = new ObservableCollection(ob1.Skip(0).Take(2));

现在如果你真的坚持那个.Range方法,你可以自己写一个扩展:

public static class ObservableCollectionExtensions
{
    public static ObservableCollection<T> Range(this ObservableCollection<T> sequence, int start, int count)
    {
         return new ObservableCollection(sequence.Skip(start).Take(count));
    }
}

现在你的代码应该可以编译了:

ObservableCollection<TheClass> ob1 = new ObservableCollection<TheClass>();
ob1.Add(...);
ob1.Add(...); 
ob1.Add(...);
ob1.Add(...); 
ObservableCollection<TheClass> ob2;

ob2 = ob1.Range(0, 2);

在你保留扩展方法的地方使用它。

public static ObservableCollection<T> Range<T>(this ObservableCollection<T> oc, uint startIndex, uint length) => 
    oc.Skip(startIndex).Take(length);

并像这样使用它:

ob2 = ob1.Range(0, 2);