无法修改 IEnumerable 中的列表?

Can't modify List inside an IEnumerable?

我有一个 IEnumerable<List<int>>,我想在其中一个列表中插入一个值。但是我不能?
在LinqPad中尝试了如下语句,Insert:

后结果集不变
var lists = new int[]{1,2,3}.Select(x => new List<int>{x});
lists.Dump();
lists.First().Insert(0, 5);
lists.Dump();

(我希望列表包含:{5, 1},但它仍然只包含 {1})

是的,你不能! IEnumerable 每次求值都会生成新的 Lists;它在您的代码中这样说:

.Select(x => new List<int>{x});

当您调用 Dump() 时,它会被评估。当您调用 First() 时,它会再次计算。然后再次转储。所有新列表!

如果您在将 IEnumerable 放入 list 变量之前对其求值(例如,通过将其放入数组),它将起作用:

var list = new int[]{1,2,3}.Select(x => new List<int>{x}).ToArray();
list.Dump();
list.First().Insert(0, 5);
list.Dump();

正如 Tim Schmelter 在您的 OP 的第一条评论中所说,Linq IEnumerable 引用是 "query",即它是对某些静态方法(最终链接在其中)的一种引用,即获取一个 IEnumerable 对象。

所以,你真正调用的不是对象引用,而是用作 IEnumerable 对象的静态方法引用的东西。它在您的代码中的声明。

因此,如果您在原始 "query" 表达式中实例化一个对象,则您无法使用查询获取的枚举对象的某些 "status changing" 属性修改其状态,您只能更改获取的值在您执行 属性 的那个精确时间,但代码中 "query" 引用的下一次调用将 shows/elaborates 始终是原始表达式,因此将始终实例化查询表达式的声明。

无论如何,你可以试试这个:

var list = new int[]{1,2,3}.Select(x => new List<int>{x});
list = new int[]{5}.First().Concat(list);

通过这种方式,您可以将相同的引用重新分配给一个查询,该查询使用您想要的值实例化一个新对象将这个值与原始引用查询获得的值相连接,这样您就改变了原始对象的状态在初始查询中实例化。