在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重现了这种行为。 {1}}在访问创建的对象之前调用ToList
会使这个问题消失。
答案 0 :(得分:6)
这种情况正在发生,因为created
是一个查询,而不是一个结果。因此,每次枚举它时,您都是从头开始重新评估Select
。
如果您希望这样做,请将created
设为实际列表,而不仅仅是代表查询的IEnumerable
。
例如,添加:
created = created.ToList();
你说:
我希望foreach语句执行查询,并触发对象的创建
这正是发生的事情。问题是每次迭代created
时都会发生对象的创建,而不仅仅是第一次。由于ElementAt()
方法迭代created
,因此只是再次创建新的A
。