【发布时间】:2013-09-25 20:43:47
【问题描述】:
在 LINQ 语句中创建新对象时,例如:
var list = new List<string>() { "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 文档指出:"Execution of the query is deferred until the query variable is iterated over in a foreach or For Each loop"。
我已经用 .NET 4.5 和 Mono 3.2.0 重现了这种行为。在访问创建的对象之前在IEnumerable 上调用ToList 可以解决此问题。
【问题讨论】:
-
它与“未执行”相反——它被执行了两次——当它第二次执行时,一个new集
As 已创建。 -
因为
created是查询而不是集合。每次访问它时,您都会再次执行它。因此,如果您在foreach之后再次枚举查询,您将获得一组全新的IEnumerable<A>。这就是延迟执行的本质。如果您要查询A的现有集合,您将更改现有的持久对象。
标签: c# .net linq foreach deferred-execution