我的问题如上所述。例如

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

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


当前回答

很抱歉,我又提了一个老问题,但由于它出现在谷歌搜索结果的第一个列表中,我想有些人会一直登陆这里。

在许多答案中,其中一些非常有价值,并且解释得很好,我想补充一个不同的观点,因为对我来说,问题还没有很好地确定。

你正在声明一个存储数据的变量,你需要它能够通过添加项目来改变吗?所以你不应该把它声明为IEnumerable。

由@NightOwl888提议

对于本例,只需声明IList而不是IEnumerable: IList items = new T[]{new T("msg")};物品。添加(新T(“msg2”));

试图绕过声明的接口限制只表明您做出了错误的选择。 除此之外,所有提议用来实现其他实现中已经存在的东西的方法都应该考虑。 允许您添加项的类和接口已经存在。为什么总是复制别人已经做过的东西?

这种考虑是在接口中抽象变量功能的目标。

TL;DR:在我看来,这些是做你需要的事情的最干净的方法:

// 1st choice : Changing declaration
IList<T> variable = new T[] { };
variable.Add(new T());

// 2nd choice : Changing instantiation, letting the framework taking care of declaration
var variable = new List<T> { };
variable.Add(new T());

当您需要使用变量作为IEnumerable时,您将能够。当你需要将它作为数组使用时,你可以调用'ToArray()',它总是应该这么简单。不需要扩展方法,仅在真正需要时才强制转换,能够在变量上使用LinQ,等等…

停止做奇怪和/或复杂的事情,因为你只是在声明/实例化时犯了一个错误。

其他回答

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

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

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

list = enumerableInstance as IList<string>;

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

var list = enumerableInstance.toList();

您不仅不能像您的状态那样添加项,而且如果您将项添加到List<T>(或几乎任何其他非只读集合),并且您有一个现有的枚举器,则枚举器将失效(从那时开始抛出InvalidOperationException)。

如果您正在聚合来自某种类型的数据查询的结果,您可以使用Concat扩展方法:

编辑:我最初在示例中使用了Union扩展,这是不正确的。我的应用程序广泛地使用它来确保重叠的查询不会重复结果。

IEnumerable<T> itemsA = ...;
IEnumerable<T> itemsB = ...;
IEnumerable<T> itemsC = ...;
return itemsA.Concat(itemsB).Concat(itemsC);

最简单的方法很简单

IEnumerable<T> items = new T[]{new T("msg")};
List<string> itemsList = new List<string>();
itemsList.AddRange(items.Select(y => y.ToString()));
itemsList.Add("msg2");

然后你可以返回list作为IEnumerable,因为它实现了IEnumerable接口

类型IEnumerable<T>不支持此类操作。IEnumerable<T>接口的目的是允许使用者查看集合的内容。不修改值。

当你执行像. tolist (). add()这样的操作时,你是在创建一个新的List<T>并向该列表添加一个值。它与原始列表没有关联。

您可以使用Add扩展方法使用添加的值创建一个新的IEnumerable<T>。

items = items.Add("msg2");

即使在这种情况下,它也不会修改原始的IEnumerable<T>对象。这可以通过持有对它的引用来验证。例如

var items = new string[]{"foo"};
var temp = items;
items = items.Add("bar");

在这组操作之后,变量temp仍然只引用值集中具有单个元素“foo”的枚举数,而项目将引用值为“foo”和“bar”的不同枚举数。

EDIT

我经常忘记Add不是IEnumerable<T>上的典型扩展方法,因为它是我最后定义的第一个扩展方法之一。在这里

public static IEnumerable<T> Add<T>(this IEnumerable<T> e, T value) {
  foreach ( var cur in e) {
    yield return cur;
  }
  yield return value;
}

当然,你可以(我把你的T-business放在一边):

public IEnumerable<string> tryAdd(IEnumerable<string> items)
{
    List<string> list = items.ToList();
    string obj = "";
    list.Add(obj);

    return list.Select(i => i);
}