我如何将一个项添加到IEnumerable集合中?

27 浏览
0 Comments

我如何将一个项添加到IEnumerable集合中?

我提出了这样一个问题。例如:

IEnumerable items = new T[]{new T("msg")};
items.ToList().Add(new T("msg2"));

但毕竟里面只有1个项。我们是否可以像List一样有一个像items.Add(item)这样的方法呢?

admin 更改状态以发布 2023年5月24日
0
0 Comments

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 IEnumerable Add(this IEnumerable e, T value) {
  foreach ( var cur in e) {
    yield return cur;
  }
  yield return value;
}

0
0 Comments

你不能这样做,因为IEnumerable不一定代表一个可以添加项目的集合。事实上,它甚至不一定代表一个集合!例如:

IEnumerable ReadLines()
{
     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"。此外,这个新对象会跟踪数组中的更改(即,每当你枚举它时,你将看到项目当前的值)。

0