无法修改IEnumerable中的List?

时间:2016-11-23 12:45:53

标签: c# linq ienumerable generic-list

我有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();

(我希望List包含:{5,1},而它仍然只包含{1})

2 个答案:

答案 0 :(得分:-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();

答案 1 :(得分:-5)

正如Tim Schmelter在您的OP的第一条评论中所说,Linq IEnumerable引用它是一个&#34;查询&#34;,它是对某些静态方法的引用(最终链接在它们之间),获取IEnumerable对象。

所以,你真正调用的是,它不是一个对象引用,而是作为IEnumerable对象的静态方法引用的东西..所以你每次使用你的linq引用后执行那些静态方法它在你的代码中的声明。

因此,如果您在原始&#34;查询&#34;中实例化一个对象。表达式你不能用一些&#34;状态改变来修改它的状态&#34;查询获取的枚举对象的属性,您只更改在执行该属性的精确时间内获取的值,但是下一次调用&#34;查询&#34;代码中的引用将显示/详细说明原始表达式,因此将在查询表达式的声明中实例化相同的对象。

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

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

通过这种方式,您可以使用一个查询来重新分配相同的引用,该查询使用您想要的值来实例化一个新对象,并使用原始引用查询获取的值来设置此值,因此您已经更改了原始对象状态。初始查询。