为什么在使用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