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