LINQ查询 – 解释为什么这些示例不同

我正在阅读“LINQ Pocket Reference”这本书,并且有一个特殊的例子(稍微修改如下),我很难理解……书中的解释有点简短,所以我想知道是否有人可以一步一步地打破它,这样才有意义……

IEnumerable query2 = "Not what you might expect"; foreach (char vowel in "aeiou") { var t = vowel; query2 = query2.Where(c => c != t); // iterate through query and output (snipped for brevity) } 

输出:

    不是你所期望的
    不是你可能xpct
    不是你的xpct
     Nt wht yu mght xpct
     Nt wht y mght xpct

这对我来说很有意义……但是,事实并非如此。

  IEnumerable query2 = "Not what you might expect"; foreach (char vowel in "aeiou") { query2 = query2.Where(c => c != vowel); // iterate through query and output (snipped for brevity) } 
    不是你所期望的
    不是你可能的xpct
    不是你期望的
    你可能会期待什么
    不是你所期望的

哪个没…

有人可以给我一个更好的解释,确切地说这里发生了什么?

第一个例子会发生的是元音的值被捕获到局部(到for循环的范围)变量中。

然后,查询的where子句将使用捕获的变量。 像这样的where子句使用匿名方法/ lambda方法,它可以捕获局部变量。 然后会发生的是它捕获变量的当前值。

但是,在第二个类中,它不捕获当前值,只捕获要使用的变量,因此,由于此变量发生更改,因此每次执行循环时,都会在最后一个上构建一个新的Where子句,但是你有点修改所有前面的那些,因为你改变了变量。

因此,在第一个示例中,您将获得此类查询:

 IEnumerable query2 = "Not what you might expect"; Char t1 = 'a'; query2 = query2.Where(c => c != t1); Char t2 = 'e'; query2 = query2.Where(c => c != t2); Char t3 = 'i'; query2 = query2.Where(c => c != t3); Char t4 = 'o'; query2 = query2.Where(c => c != t4); Char t5 = 'u'; query2 = query2.Where(c => c != t5); 

在第二个例子中,你得到这个:

 IEnumerable query2 = "Not what you might expect"; Char vowel = 'a'; query2 = query2.Where(c => c != vowel); vowel = 'e'; query2 = query2.Where(c => c != vowel); vowel = 'i'; query2 = query2.Where(c => c != vowel); vowel = 'o'; query2 = query2.Where(c => c != vowel); vowel = 'u'; query2 = query2.Where(c => c != vowel); 

当你执行第二个例子时, vowel的值将是’u’,所以只有u才会被删除。 但是,你在同一个字符串上有5个循环去除’u’,但只有第一个当然会这样做。

这个变量的捕获是我们在使用匿名方法/ lambdas时所遇到的事情之一,你可以在这里阅读更多相关内容: C#深度:闭包之美 。

如果您将该页面向下浏览到比较捕获策略:复杂性与功率下的文本,您将找到此行为的一些示例。

实际上,通过重读它,它是有道理的。 使用temp变量意味着在查询中捕获了temp本身…我们正在评估循环五次,因此每个查询版本都有五个实例化的临时变量引用。

在没有temp变量的情况下,只有对循环变量的引用。

所以五个引用与一个引用相比。 这就是它产生如图所示结果的原因。

在第一种情况下,一旦完全评估了循环,查询就使用了对temp变量的五个引用,因此分别剥离了a,e,i,o和u。

在第二种情况下,它正在做同样的事情……只有所有五个引用都属于同一个变量,显然只包含一个值。

故事的道德:认为“参考”而不是“价值”。

那么,这对现在的其他人有意义吗?