C#Linq打印的值与调试模式中显示的值不同

时间:2017-07-27 10:17:11

标签: c# linq

var counter=0;
var array = new int[] {0, 1, 2, 3,4};

var test = array.Select(a => counter++);

foreach (var item in test)
{
    Console.WriteLine(item);
}

Console.ReadLine();

当我运行上面的代码时,控制台会输出0,1,2,3,4。 但是,当我在调试模式下扩展测试数组时,我可以看到10到14之间的数字。为什么? 另外,你能帮我解释为什么控制台不打印1,2,3,4,5,因为它应该返回增量计数器。

DebugMode

2 个答案:

答案 0 :(得分:2)

输出不断变化的原因是test在您枚举之前不会被实际评估。因此,打开调试视图会使其评估枚举。然后每次枚举它时,每次counter变量增加时它都会再次运行。因此,您可以多次运行for循环或多次打印test.First()来获得一些有趣的结果。

您可以通过强制将枚举实体化为列表来阻止这种情况:

var test = array.Select(a => counter++).ToList();
//                                     ^^^^^^^^^

至于为什么它从0开始,因为这个上下文中的++是一个后增量运算符,意味着它返回值然后递增。如果您希望它从1开始,请改为为变量添加前缀:

var test = array.Select(a => ++counter).ToList();

答案 1 :(得分:1)

这是正常的。当您使用Select方法时,您会得到一个惰性列表,这意味着当您访问它时将对其进行评估。在这里,您可以访问它两次,当您执行foreach时,当您查看调试器时,每次都会执行您的选择Func,从而递增计数器。 如果替换为

var test = array.Select(a => counter++).ToList();

它不再是懒惰的,并且在您调用ToList()时将执行一次。然而,保持懒惰可能会很有趣,特别是如果你想稍后添加一些条件,例如附加一些Where条件,你不希望你的查询在你完成构建之前执行。

你的计数器从零开始,因为counter ++会首先给你这个值,然后只递增它。如果你想从1开始,你可以将counter初始化为1或者用++计数器替换counter ++,它将首先递增然后返回。