如何有效地 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
并通过使用 Skip
和Take
像这样:
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);
类似(伪代码)
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
并通过使用 Skip
和Take
像这样:
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);