3

我在使用这个简单的代码时遇到了问题,我不明白为什么 c# 会这样。

问题似乎是 c# 在 Lists 中使用 Lists 时使用的是 Linq 表达式引用而不是值。

在数字循环中,我根据列表选择数字,它们都存在,因此所有数字都应添加到列表 {1,2,3} 中。

当您看到控制台的输出时,行为正常,它在数字循环内显示 {1,2,3}。

问题出在列表的循环上,在这里,Linq 似乎只将最后一个数字添加到列表中,因此它输出 {3,3,3}。

我知道我不需要列表中的整数列表,但这只是为了证明一点,这很奇怪,这是一个已知的“错误”吗?

编辑:这似乎是它在 5.0 之前的 c# 中应该如何工作。在 C# 5.0(VS2012+ 编译器)中,此行为已修改为我所期望的

static void Main()
{
    var list = new List<IEnumerable<int>>();
    var numbers = new[] {1, 2, 3};
    var numbers2 = new[] {1, 2, 3};

    foreach (var number in numbers)
    {
        var result = from s in numbers2
                     where s == number
                     select s;

        Console.WriteLine(result.First()); // outputs {1,2,3}
        list.Add(result);
    }

    foreach (var num in list)
    {
        Console.WriteLine(num.First()); // outputs {3,3,3}
    }
}

输出

1 2 3 3 3 3

4

4 回答 4

8

这个

list.Add(result);

不符合您的预期。它不会添加数字列表。它添加了一个查询查询是按需执行的。因为,在您的最终输出循环number = 3中,所有三个查询都返回3.

如果要添加列表,请通过附加ToList来强制立即执行查询:

list.Add(result.ToList());
于 2013-10-16T12:49:22.637 回答
2

是的,这是众所周知的。我相信它已在 c# 5 中修复。

您可以在 foreach 中声明一个值,然后在 Console.WriteLine 中使用该值来停止它,只使用 num 的结束值。

请参阅this以获得更清晰的解释。 foreach 标识符和闭包

于 2013-10-16T12:50:36.540 回答
2

执行查询时,数字== 3。

这是因为第一个 foreach 循环已经执行并且最后一个赋值给number实际上是 3。

LINQ 查询在必要时延迟执行(例如,当您调用 a 时ToList())。

这不是一个奇怪的结果,这就是它的本意。

顺便说一句,在 C# 5.0(VS2012+ 编译器)中,此行为已修改为您所期望的。

于 2013-10-16T12:55:13.947 回答
1

仅当需要其结果时才执行 linq 表达式。

所以

var result = from s in numbers2
where s == number
select s;

将在需要 result 的值时执行。但是,如果您希望立即计算表达式,则需要从中获取结果并创建一个对象。

喜欢

var result = (from s in numbers2
where s == number
select s).ToList();

如果您想查看正确的流程,请在“from s in numbers2....”的行上设置一个断点,然后查看它何时被击中...

希望能帮助到你...

于 2013-10-16T12:57:26.060 回答