这两段代码有什么区别?

时间:2015-09-21 08:44:56

标签: c#

int[] div = new int[] {2,3,5};
IEnumerable<int> seq = new int[] {10,15,20,25,30};
int x;
for (int i=0; i<div.Length; i++){
  x = div[i];
  seq = seq.Where( s=> s%x ==0);
}
seq = seq.ToList();

int[] div = new int[] {2,3,5};
IEnumerable<int> seq = new int[] {10,15,20,25,30};
for (int i=0; i<div.Length; i++){
  int y = div[i];
  seq = seq.Where( s=> s%y ==0);
}
seq = seq.ToList();

第一个seq的最终值是10,15,20,25,30,第二个是30。 我对int x;之间的区别感到有点困惑 和int y = div[i];。有人可以向我解释一下吗? 谢谢!

2 个答案:

答案 0 :(得分:5)

调用seq = seq.Where( s=> s%x ==0);不会迭代元素。它只创建一个封装迭代的IEnumarable,可以在fututre中迭代。

因此,如果您在循环之前声明了x变量,那么您在Where()中传递的lambda将使用相同的变量。由于您在循环中更改其值,因此最终只会实际使用最后一个。

而不是表达式:

seq.Where( s=> s % 2 == 0).Where( s=> s % 3 == 0).Where( s=> s % 5 == 0);

你得到:

seq.Where( s=> s % 5 == 0).Where( s=> s % 5 == 0).Where( s=> s % 5 == 0);

答案 1 :(得分:2)

结果不同,因为您在LINQ的Where()参数中使用lambda表达式。 Where()中所有lambda的实际执行是在两个示例的最后一行 - 您执行.ToList()的行上执行的。看看Variable Scope in Lambda Expressions

示例中的差异在于您如何初始化x/y

在第一个示例中,无论x的迭代次数如何,变量foreach只有一个内存槽。 x始终指向内存中的相同位置。因此,最后一行只有x的一个值,它等于div[2]

在第二个示例中,在循环的每次迭代中为y创建了单独的内存槽。在程序评估时,y的每次迭代中foreach指向的地址都会发生变化。您可能会想象它有多个y变量,如y_1y_2,...因此,当评估Where() s中的实际lambdas时{{1}的值每个人都有所不同。