我正在阅读"LINQ Pocket Reference"一书,并且有一个特殊的例子(下面稍作修改),我很难理解......书中的解释有点简短,所以我想知道是否有人可以一步一步地分解它,这样才有意义......
IEnumerablequery2 = "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) }
输出:
Not wht you might expect Not wht you might xpct Not wht you mght xpct Nt wht yu mght xpct Nt wht y mght xpct
这对我来说很有意义......然而,事实并非如此.
IEnumerablequery2 = "Not what you might expect"; foreach (char vowel in "aeiou") { query2 = query2.Where(c => c != vowel); // iterate through query and output (snipped for brevity) }
Not wht you might expect Not what you might xpct Not what you mght expect Nt what yu might expect Not what yo might expect
哪个没...
有人能给我一个更好的解释,确切地说这里发生了什么?
第一个例子的结果是元音的值被捕获到局部(到for循环的范围)变量中.
然后,查询的where子句将使用捕获的变量.像这样的where子句使用匿名方法/ lambda方法,它可以捕获局部变量.然后会发生的是它捕获变量的当前值.
但是,在第二个类中,它不捕获当前值,只捕获要使用的变量,因此,由于此变量发生更改,因此每次执行循环时,都会在最后一个上构建一个新的Where子句,但是你有点修改所有前面的那些,因为你改变了变量.
因此,在第一个示例中,您将获得此类查询:
IEnumerablequery2 = "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);
在第二个例子中,你得到这个:
IEnumerablequery2 = "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',但只有第一个当然会这样做.
这个变量的捕获是我们在使用匿名方法/ lambda时所遇到的事情之一,你可以在这里阅读更多相关内容:C#深度:闭包之美.
如果您将该页面浏览到比较捕获策略:复杂性与功能下的文本,您将找到此行为的一些示例.