我的问题如上所述。例如

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

但毕竟里面只有一项。我们能不能有一个items.Add(item)方法,比如List<T>?


当前回答

不,IEnumerable不支持向它添加项目。另一种解决方案是

var myList = new List(items);
myList.Add(otherItem);

其他回答

实现IEnumerable和IEnumerator(从IEnumerable返回)的实例没有任何允许修改收集的api,接口提供只读api。

实际上改变集合的2种方法:

如果实例恰好是一些写API的集合(例如List),你可以尝试转换为这种类型:

list = enumerableInstance as IList<string>;

从IEnumerable中创建一个列表(例如,通过LINQ扩展方法toList():

var list = enumerableInstance.toList();

我只是想说,除了Enumerable。Concat扩展方法,似乎有另一个方法名为Enumerable。在. net Core 1.1.1中添加。后者允许您将单个项连接到现有序列。所以Aamol的答案也可以写成

IEnumerable<T> items = new T[]{new T("msg")};
items = items.Append(new T("msg2"));

不过,请注意,这个函数不会改变输入序列,它只是返回一个包装器,将给定的序列和附加的项放在一起。

在.net Core中,有一个方法Enumerable。附加就是这样做的。

该方法的源代码可在GitHub.....上获得实现(比其他答案中的建议更复杂)值得一看:)。

一对简短,甜蜜的扩展方法IEnumerable和IEnumerable<T>做它为我:

public static IEnumerable Append(this IEnumerable first, params object[] second)
{
    return first.OfType<object>().Concat(second);
}
public static IEnumerable<T> Append<T>(this IEnumerable<T> first, params T[] second)
{
    return first.Concat(second);
}   
public static IEnumerable Prepend(this IEnumerable first, params object[] second)
{
    return second.Concat(first.OfType<object>());
}
public static IEnumerable<T> Prepend<T>(this IEnumerable<T> first, params T[] second)
{
    return second.Concat(first);
}

优雅(好吧,非通用版本除外)。可惜这些方法不在BCL中。

不能,因为IEnumerable<T>不一定表示可以添加项的集合。事实上,它并不一定代表一个集合!例如:

IEnumerable<string> ReadLines()
{
     string s;
     do
     {
          s = Console.ReadLine();
          yield return s;
     } while (!string.IsNullOrEmpty(s));
}

IEnumerable<string> lines = ReadLines();
lines.Add("foo") // so what is this supposed to do??

但是,您可以创建一个新的IEnumerable对象(未指定类型),当它被枚举时,将提供旧对象的所有项,以及您自己的一些项。你使用Enumerable。为此Concat:

 items = items.Concat(new[] { "foo" });

这不会改变数组对象(无论如何,您不能将项插入到数组中)。但它将创建一个新对象,该对象将列出数组中的所有项,然后是“Foo”。此外,新对象将跟踪数组中的变化(即无论何时枚举它,您都将看到项目的当前值)。