Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实现动态FlatCollection<;T>;_C#_Algorithm_Data Structures_Collections - Fatal编程技术网

C# 实现动态FlatCollection<;T>;

C# 实现动态FlatCollection<;T>;,c#,algorithm,data-structures,collections,C#,Algorithm,Data Structures,Collections,我需要创建或使用现有的.NET FW FlatCollection。 我所说的FlatCollection是指,当通过Add方法/函数插入元素时,将检查元素的集合,如果该元素是IEnumerable,则将从该IEnumerable中获取所有元素并将其添加到集合中。(此行为仅适用于根IEnumerable,但是,将其递归应用于子IEnumerable也可能是好的,尽管更难)。诀窍在于,此FlatCollection作为索引集合,需要保持其元素的顺序 假设一个用户向集合添加了一个由3个元素组成的IE

我需要创建或使用现有的.NET FW FlatCollection。 我所说的FlatCollection是指,当通过Add方法/函数插入元素时,将检查元素的集合,如果该元素是IEnumerable,则将从该IEnumerable中获取所有元素并将其添加到集合中。(此行为仅适用于根IEnumerable,但是,将其递归应用于子IEnumerable也可能是好的,尽管更难)。诀窍在于,此FlatCollection作为索引集合,需要保持其元素的顺序

假设一个用户向集合添加了一个由3个元素组成的IEnumerable,然后在某个时刻向引用的集合添加了一个新元素;FlatCollection需要注意列表的大小已更改,并更新其内部集合以反映新元素,从而保持顺序。因此,例如,如果用户在两个单个元素之间添加一个空集合,然后用3个元素填充该集合,那么这两个单个元素仍将位于新添加的3个元素之前和之后

当然,我可以通过从集合继承并定义所有这些行为来实现这一点,但这很棘手,因为需要对添加的IEnumerable(IEnumerable没有计数)中的项数及其在集合中的起始索引进行计数。首先想到的是使用链表作为内部集合,因为您将调整很多大小,但我不确定什么是最好的

但是,如果有一种更简单的方法来实现这一点,而不是从头开始实现整个过程,即使用现有的.NET FrameWork元素,我想知道!因为这是我问题的目的

总结如下: 我正在寻找实现FlatCollection的最佳性能和最简单的方法,可能使用.NET FW元素。

如果将“FlatCollection”设置为简单的
列表
,则可以满足您的所有需要

List listOfEnumerables=新建。。。
可数平坦=
选择(x=>x);
如果要隐藏详细信息,也可以将该调用包装到类中:

 class FlatCollection<T> : IEnumerable<T>
 {
    List<IEnumerable<T>> list = new ...

    public Add(T item) { list.Add(Enumerable.Repeat(item, 1);}
    public Add(IEnumerable<T> item) { list.Add(item);}

    // use Enumerable.SelectMany to imeplent IEnumerable
  }
类集合:IEnumerable
{
列表=新的。。。
公共Add(T项){list.Add(可枚举.重复(项,1);}
公共添加(IEnumerable项){list.Add(项);}
//使用Enumerable.SelectMany到imeplent IEnumerable
}

这看起来像某种树结构。每个“集合”都是节点,每个节点都可以有任意数量的子节点,值都是叶。通过按顺序遍历叶,您可以创建所需的“平面”集合。它还可以递归工作,因此您可以询问任何节点,并将为您提供正确的“平面子集合”.

您无法设置此集合中的第一项,因为
IEnumerable
不提供任何突变操作。这是否支持以前添加的IEnumerable的索引扩展?如果用户更改以前添加的IEnumerable,更改是否会传播到FlatCollection?@Servy不确定您的意思“您不能设置第一项”…我不认为集合本身需要向现有的
IEnumerable
(如listOfEnumerables[3]。add(newItem)`)。@FranciscoAguilera-是的…如果您添加的是实枚举而不是副本-即添加
myEnumerable.ToList()
将不起作用…@AlexeiLevenkov Enumerable.Repeat(item,1)返回一个IEnumerable。我不明白将此Enumerable中的所有项目添加到列表将如何支持我所说的索引扩展,您能澄清一下吗?(我还假设您打算使用list.AddRange而不是list.Add)谢谢!您需要实现什么接口?如果您只需要
IEnumerable
,我只需要保留原始集合,然后懒洋洋地迭代它们。@Jonsket这是我为Windows Phone 8编写的自定义CompositeCollection实现。因此,ItemsControl的ItemsSource调用任何接口方法来填充此类ItemsControl的项就是我需要的项。@JonSkeet起初我以为它只使用了枚举器,因为ItemsSource的类型是IEnumerable,但是在编写CompositeEnumerator()之后以这种方式枚举惰性集合,我注意到它不仅仅使用IEnumerable中的方法。NET CompositeCollection类使用IList、ICollection、IEnumerable、INotifyCollectionChanged,因此我需要使用这些的泛型版本。@Franciscoaguiera您应该真正将其视为树而不是集合。我相信这会使解决这个问题变得更容易。@Ephoric这听起来确实是一个不错的方法,只要这个树结构公开了必要的接口元素。我不知道您是否看到了,但我需要这个FlatCollection来实现IList、ICollection、IEnumerable和INotifyCollectionChanged(将更改传播到UI)。我不确定实施这些措施是否违反了这种树状结构的原则。
 class FlatCollection<T> : IEnumerable<T>
 {
    List<IEnumerable<T>> list = new ...

    public Add(T item) { list.Add(Enumerable.Repeat(item, 1);}
    public Add(IEnumerable<T> item) { list.Add(item);}

    // use Enumerable.SelectMany to imeplent IEnumerable
  }