我如何将一个项添加到IEnumerable集合中?
我如何将一个项添加到IEnumerable集合中?
我提出了这样一个问题。例如:
IEnumerable items = new T[]{new T("msg")}; items.ToList().Add(new T("msg2"));
但毕竟里面只有1个项。我们是否可以像List
一样有一个像items.Add(item)
这样的方法呢?
admin 更改状态以发布 2023年5月24日
IEnumerable
类型不支持这样的操作。 IEnumerable
接口的目的是允许消费者查看集合的内容,而不是修改值。
当您执行像.ToList().Add()这样的操作时,您正在创建一个新的List
并在该列表中添加值。它与原始列表没有关联。
您可以使用Add扩展方法创建一个具有添加值的新IEnumerable
。
items = items.Add("msg2");
即使在这种情况下,它也不会修改原始的IEnumerable
对象。可以通过持有对它的引用进行验证。例如:
var items = new string[]{"foo"}; var temp = items; items = items.Add("bar");
在这组操作之后,变量temp仍将只引用具有单个元素“foo”在值集合中的可枚举对象,而items将引用具有值“foo”和“bar”的不同可枚举对象。
编辑
我经常忘记Add不是IEnumerable
上典型的扩展方法,因为它是我最先定义的扩展方法之一。下面是它的代码:
public static IEnumerableAdd (this IEnumerable e, T value) { foreach ( var cur in e) { yield return cur; } yield return value; }
你不能这样做,因为IEnumerable
不一定代表一个可以添加项目的集合。事实上,它甚至不一定代表一个集合!例如:
IEnumerableReadLines() { string s; do { s = Console.ReadLine(); yield return s; } while (!string.IsNullOrEmpty(s)); } IEnumerable lines = ReadLines(); lines.Add("foo") // so what is this supposed to do??
不过,你可以创建一个新的IEnumerable
对象(未指定类型),当遍历它时,它将提供旧对象中的所有项目以及一些自己的项目。你可以使用Enumerable.Concat
来实现:
items = items.Concat(new[] { "foo" });
这将不会改变数组对象(无论如何,你都不能向数组中插入项目)。但它将创建一个新对象,其中将列举数组中所有项目,以及添加的"Foo"。此外,这个新对象会跟踪数组中的更改(即,每当你枚举它时,你将看到项目当前的值)。