使用的foreach时,为什么不执行这个LINQ查询? [英] Why is this LINQ query not executed when using foreach?

查看:494
本文介绍了使用的foreach时,为什么不执行这个LINQ查询?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当在LINQ声明中创建新的对象,例如:

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();

通过A类看起来像这样:

With class A looking like this:

class A
{
    public string Label;
}

再修改属性,是在一个foreach循环

和b
$ b

And then modifying properties in A with a foreach loop:

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



为什么值不在<$ C $访问对象时设置C>的IEnumerable 之后。例如。以下断言失败:

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);



我不知道为什么会这样。我希望在foreach语句来执行查询,并触发对象的创建。 MSDN文档状态:查询的执行被推迟到查询变量是在foreach或每个迭代循环

我已经再现.NET 4.5和Mono 3.2.0此行为。调用了ToList 的IEnumerable 之前访问创建的对象,使这个问题消失。

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.

推荐答案

这是怎么回事,因为创建是一个查询,而不是结果。所以,每次你列举它的时候,你正在评估的选择重新从头开始。

It's happening because created is a query, not a result. So, every time you enumerate it, you're evaluating the Select over again from scratch.

如果你想这个工作,使创建的实际列表,而不仅仅是一个的IEnumerable 表示查询。

If you want this to work, make created an actual list, rather than just an IEnumerable representing a query.

例如,添加:

created = created.ToList();

您说的:

我希望在foreach语句来执行查询,并触发对象

I would expect the foreach-statement to execute the query, and trigger the creation of the objects

这是什么正在发生。问题是对象的创建发生在每次迭代创建,不只是第一次的时间。由于在创建,它只是创造新的 A 的ElementAt()方法迭代C $ C> s键一下。

This is exactly what is happening. The problem is the creation of the objects happens every time you iterate over created, not just the first time. Since the ElementAt() method iterates over created, it's just creating new As again.

这篇关于使用的foreach时,为什么不执行这个LINQ查询?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆