为什么在使用foreach时不执行此LINQ查询?
在LINQ语句中创建新对象时,例如:
var list = new List() { "a", "b", "c" }; var created = from i in list select new A();
A级看起来像这样:
class A { public string Label; }
然后使用foreach循环修改A中的属性:
foreach (var c in created) { c.Label = "Set"; }
为什么在访问IEnumerable
的对象后未设置值。 例如,以下断言失败:
Assert.AreEqual("Set", created.ElementAt(2).Label);
我想知道为什么会这样。 我希望foreach语句执行查询,并触发对象的创建。 MSDN文档声明: “查询的执行被推迟,直到在foreach或For Each循环中迭代查询变量” 。
我用.NET 4.5和Mono 3.2.0重现了这种行为。 在访问创建的对象之前在IEnumerable
上调用ToList
会使这个问题消失。
它正在发生,因为created
是一个查询,而不是一个结果。 因此,每次枚举它时,您都会从头开始评估Select
over。
如果您希望这样做,请created
一个实际列表,而不仅仅是表示查询的IEnumerable
。
例如,添加:
created = created.ToList();
你说:
我希望foreach语句执行查询,并触发对象的创建
这正是发生的事情。 问题是每次迭代created
时都会创建对象,而不仅仅是第一次。 由于ElementAt()
方法迭代created
,它只是再次创建新的A