10

When creating new objects in a LINQ statement, for example:

var list = new List<string>() { "a", "b", "c" };
var created = from i in list select new A();

With class A looking like this:

class A
{
    public string Label;
}

And then modifying properties in A with a foreach loop:

foreach (var c in created) {
    c.Label = "Set";
}

Why are the values not set when accessing the objects in the IEnumerable afterwards. E.g. the following assertion fails:

Assert.AreEqual("Set", created.ElementAt(2).Label);

I wonder why this happens. I would expect the foreach-statement to execute the query, and trigger the creation of the objects. MSDN documentation states: "Execution of the query is deferred until the query variable is iterated over in a foreach or For Each loop".

I have reproduced this behavior with .NET 4.5 and Mono 3.2.0. Calling ToList on the IEnumerable before accessing the created object makes this problem go away.

4

1 回答 1

6

它发生是因为created是查询,而不是结果。所以,每次你枚举它时,你都是Select从头开始重新评估。

如果您希望它起作用,请制作created一个实际列表,而不仅仅是一个IEnumerable代表查询。

例如,添加:

created = created.ToList();

你说:

我希望 foreach 语句执行查询,并触发对象的创建

这正是正在发生的事情。问题是每次迭代时都会创建对象created,而不仅仅是第一次。由于该ElementAt()方法迭代了created,它只是A再次创建新的。

于 2013-09-20T12:49:03.640 回答