添加到 IEnumerable 的代码
Posted
技术标签:
【中文标题】添加到 IEnumerable 的代码【英文标题】:Code for adding to IEnumerable 【发布时间】:2013-03-23 13:20:45 【问题描述】:我有一个这样的枚举器
IEnumerable<System.Windows.Documents.FixedPage> page;
如何添加页面(例如:D:\newfile.txt)?我尝试过Add
、Append
、Concat
等,但没有任何效果。
【问题讨论】:
你试过Concat
?如何?您可以将单个页面包装在一个集合中,例如new[]singlePage
。然后你可以将它用于Enumerable.Concat
:var pages = page.Concat(new[]singlePage);
【参考方案1】:
是的,有可能
可以将序列(IEnumerables)连接在一起并将连接的结果分配给新序列。 (你不能改变原来的顺序。)
内置的Enumerable.Concat()
只会连接另一个序列;但是,很容易编写一个扩展方法,让您将一个标量连接到一个序列。
以下代码演示:
using System;
using System.Collections.Generic;
using System.Linq;
namespace Demo
public class Program
[STAThread]
private static void Main()
var stringList = new List<string> "One", "Two", "Three";
IEnumerable<string> originalSequence = stringList;
var newSequence = originalSequence.Concat("Four");
foreach (var text in newSequence)
Console.WriteLine(text); // Prints "One" "Two" "Three" "Four".
public static class EnumerableExt
/// <summary>Concatenates a scalar to a sequence.</summary>
/// <typeparam name="T">The type of elements in the sequence.</typeparam>
/// <param name="sequence">a sequence.</param>
/// <param name="item">The scalar item to concatenate to the sequence.</param>
/// <returns>A sequence which has the specified item appended to it.</returns>
/// <remarks>
/// The standard .Net IEnumerable extensions includes a Concat() operator which concatenates a sequence to another sequence.
/// However, it does not allow you to concat a scalar to a sequence. This operator provides that ability.
/// </remarks>
public static IEnumerable<T> Concat<T>(this IEnumerable<T> sequence, T item)
return sequence.Concat(new[] item );
【讨论】:
是的,它可能,但它非常效率低下! 澄清一下,它确实不将一个项目附加到现有集合中,它会创建一个附加该项目的新序列。 可以修改现有的集合。请参阅下面的答案。【参考方案2】:IEnumerable<T>
不包含修改集合的方法。
您将需要实现ICollection<T>
或IList<T>
,因为它们包含添加和删除功能。
【讨论】:
【参考方案3】:如果你知道 IEnumerable 的原始类型是什么,你可以修改它...
List<string> stringList = new List<string>();
stringList.Add("One");
stringList.Add("Two");
IEnumerable<string> stringEnumerable = stringList.AsEnumerable();
List<string> stringList2 = stringEnumerable as List<string>;
if (stringList2 != null)
stringList2.Add("Three");
foreach (var s in stringList)
Console.WriteLine(s);
这个输出:
One
Two
Three
更改 foreach 语句以迭代 stringList2
或 stringEnumerable
,您将得到相同的结果。
反射可能有助于确定 IEnumerable 的 real 类型。
不过,这可能不是一个好习惯……不管给你 IEnumerable 的东西,都可能不希望以这种方式修改集合。
【讨论】:
最好将 stringList2 转换为 ICollectionIEnumerable<T>
是只读接口。您应该改用IList<T>
,它提供了添加和删除项目的方法。
【讨论】:
如果您要使用更具体的界面,我会使用您可以使用的***别的界面,即ICollection<T>
。【参考方案5】:
IEnumerable
是不可变的。您不能添加项目,也不能删除项目。System.Collections.Generic
中的类返回此接口,以便您可以迭代集合中包含的项目。
来自 MSDN
Exposes the enumerator, which supports a simple iteration over a collection of a specified type.
有关 MSDN 参考,请参阅 here。
【讨论】:
【参考方案6】:试试
IEnumerable<System.Windows.Documents.FixedPage> page = new List<System.Windows.Documents.FixedPage>(your items list here)
或
IList<System.Windows.Documents.FixedPage> page = new List<System.Windows.Documents.FixedPage>(1);
page.Add(your item Here);
【讨论】:
【参考方案7】:您不能向IEnumerable<T>
添加元素,因为它不支持添加操作。您要么必须使用ICollection<T>
的实现,要么尽可能将IEnumerable<T>
转换为ICollection<T>
。
IEnumerable<System.Windows.Documents.FixedPage> page;
....
ICollection<System.Windows.Documents.FixedPage> pageCollection
= (ICollection<System.Windows.Documents.FixedPage>) page
如果演员是不可能的,使用例如
ICollection<System.Windows.Documents.FixedPage> pageCollection
= new List<System.Windows.Documents.FixedPage>(page);
你可以这样做:
ICollection<System.Windows.Documents.FixedPage> pageCollection
= (page as ICollection<System.Windows.Documents.FixedPage>) ??
new List<System.Windows.Documents.FixedPage>(page);
后者几乎可以保证您拥有一个可修改的集合。不过有可能在使用 cast 时成功获取集合,但所有修改操作都抛出NotSupportedException
。对于只读集合来说就是这样。在这种情况下,使用构造函数的方法是唯一的选择。
ICollection<T>
接口实现了IEnumerable<T>
,因此您可以在当前使用page
的任何地方使用pageCollection
。
【讨论】:
以上是关于添加到 IEnumerable 的代码的主要内容,如果未能解决你的问题,请参考以下文章
InvalidCastException:无法将“System.Collections.Generic.List”类型的对象转换为 System.Collections.Generic.IEnumer
带有 IEnumerable<child> 成员的 ViewModel 在 POST 上未正确绑定 [重复]
如何将多个 IEnumerable<IEnumerable<T>> 列表添加到 IEnumerable<List<int>>