将单个元素添加到IEnumerable集合的最佳方法是什么?

时间:2010-11-15 22:38:57

标签: c# .net ienumerable

我很惊讶地发现似乎没有一种方法可以将单个元素添加到IEnumerable集合中。

如何将单个元素添加到IEnumerable集合中?

8 个答案:

答案 0 :(得分:24)

你无法真正向IEnumerable添加元素,因为它应该是只读的。你最好的选择是:

return new List<Foo>(enumerable){ new Foo() };

return enumerable.Concat(new [] { new Foo() });

答案 1 :(得分:20)

IEnumerable的意思是它是一个只读拉式样式集合。如果需要,可以通过执行以下操作来模拟添加:

public static IEnumerable<T> Add<T>(this IEnumerable<T> source, T additionalItem)
{
   foreach(var item in source)
   {
      yield return item;
   }

   yield return additionalItem;
}

答案 2 :(得分:7)

我想在这里指出其他一些答案,IEnumerable不是一个只读集合,它根本不是一个集合。它是一个定义如何迭代集合的接口。

如果要添加对象,则应将对象添加到具体集合类中,或者至少使用不同的接口。

答案 3 :(得分:6)

您可以将其与单例数组连接:

IEnumerable xs;
xs.Concat(new[]{x});

答案 4 :(得分:4)

记住其他人所说的关于不能真正“添加”到可枚举的内容,你仍然可以模拟添加。事实上,我认为你可以通过将序列变形成一个实际上“包含”该项目的新序列来“添加”项目到一个序列(如果你不相信我,只需迭代新序列!)

您还可以将单个项目表达为可枚举的内容:

//ToEnumerable might not be the best name here
public static IEnumerable<T> ToEnumerable<T>(this T item)
{
    return Enumerable.Repeat(item,1);
}

public static IEnumerable<T> ToEnumerable<T>(this T item)
{
    yield return item;
}

然后你可以将一个项目“添加”到这样的可枚举项中:

var items = GetSomeItems();

var itemsWithNewItemOnEnd = items.Concat(somenewitem.ToEnumerable());

var itemsWithNewItemAtStart = somenewitem.ToEnumerable().Concat(items);

您甚至可以将项目插入序列中的其他位置(假设您知道要插入的位置):

var itemsWithNewItemInserted = items.Take(5).Concat(somenewitem.ToEnumerable()).Concat(items.Skip(5));

完成操作后(即您已经操作了序列以使其“包含”您想要包含的内容),您可能希望通过ToArray或ToList方法从序列中创建数组或列表:

var itemsWithNewItemInserted = items.Take(5).Concat(somenewitem.ToEnumerable()).Concat(items.Skip(5)).ToList();

现在itemsWithNewItemInserted是一个列表,其中包含原始列表中的所有所需项目,新项目插入到中间。

过多地使用这样的序列(采取,跳过,插入等)可能会花费你一段时间,因为每个添加的扩展方法(Take,Skip等)都会导致序列被多次迭代,但是列表理解语法确实可以更容易地表达使用常规迭代看起来更复杂的操作。

此外,这里有一些链接讨论将单个项目表示为IEnumerable:

Passing a single item as IEnumerable<T>

Is there a neater linq way to 'Union' a single item?

答案 5 :(得分:2)

IEnumerable是一个只读集合,ICollection提供了一个带有Add和Remove的可变集合。

但是你可以创建一个新的IEnumerable包含原始IEnumerable中的所有项目和一个新项目,通过连接2个列表:

var newCollection = original.Concat(new[]{element});

答案 6 :(得分:0)

IEnumerable旨在迭代项目。它并不总是以集合作为后盾。此外,在循环收集集合时,无法修改集合。

如果您需要在迭代时更新集合,则需要在开始foreach循环之前制作副本。 LINQ的ToList()方法是一种很好的方法。

答案 7 :(得分:0)

可能不是您正在寻找的答案,但使用泛型集合类似乎总能为我解决这些类型的问题。他们中的大多数都有.Add(T)方法。