【发布时间】:2014-03-28 20:41:17
【问题描述】:
我需要创建或使用现有的 .NET FW FlatCollection。 我所说的 FlatCollection 是一个集合,当通过 Add 方法/函数插入一个元素时,它将检查该元素,如果该元素是 IEnumerable,则将从该 IEnumerable 中获取所有元素并将它们添加到收藏。 (此行为仅适用于根 IEnumerable,但是,将其递归地应用于子 IEnumerable 也可能很好,尽管更难)。诀窍是,这个 FlatCollection 作为一个索引集合,需要保持其元素的顺序。
假设用户向集合中添加了一个由 3 个元素组成的 IEnumerable,然后在某个时间点向被引用的集合中添加了一个新元素; FlatCollection 需要注意列表的大小发生了变化,并更新其内部集合以反映新元素,保持排序。因此,例如,如果用户在两个单元素之间添加了一个 Empty 集合,然后用 3 个元素填充该集合,则这两个单元素仍将位于新添加的 3 个元素之前和之后。
当然,我可以通过从集合继承并定义所有这些行为来自己实现这一点,但这很棘手,因为您需要对添加的 IEnumerable 中的项目数进行计数(IEnumerable 没有计数),以及它在集合中的起始索引。想到的第一件事是使用链表作为内部集合,因为您会调整很多大小,但我不确定什么是最好的。
但是,如果有一种更简单的方法可以做到这一点,而不是从头开始实施整个事情。使用我想知道的现有 .NET FrameWork 元素!因为这是我的问题的目的。
总结一下: 我正在寻找实现 FlatCollection 的最佳性能和最简单的方法,可能使用 .NET FW 元素。
【问题讨论】:
-
需要实现哪些接口?如果您只需要
IEnumerable<T>,我会保留原始 集合,然后懒惰地迭代它们。 -
@JonSkeet 这是我为 Windows Phone 8 编写的自定义 CompositeCollection 实现。因此,ItemsControl 的 ItemsSource 调用任何接口方法来填充此类 ItemsControl 的项目都是我需要的。
-
@JonSkeet 起初我以为它只使用了枚举器,因为 ItemsSource 是 IEnumerable 类型,但是,在编写了一个以这种方式枚举惰性集合的 CompositeEnumerator (1drv.ms/P9mzRx) 之后,我注意到它不仅仅使用 IEnumerable 中的方法。 .NET CompositeCollection 类使用 IList、ICollection、IEnumerable、INotifyCollectionChanged,所以我需要使用这些的通用版本。
-
@FranciscoAguilera 您真的应该将其视为树而不是集合。我相信它会让解决这个问题变得更容易。
-
@Euphoric 听起来绝对是个好方法,前提是这个树形结构暴露了必要的界面元素。我不知道你是否看到,但我需要这个 FlatCollection 来实现 IList
、ICollection 、IEnumerable 和 INotifyCollectionChanged(将更改传播到 UI)。我不确定实施这些是否违反了这种树结构的原则。
标签: c# algorithm data-structures collections