我正在阅读“LINQ Pocket Reference”这本书,并且有一个特殊的例子(下面稍作修改),我很难理解...... 书中的解释有点简短,所以我想知道是否有人可以一步一步地为我分解它,这样才有意义......
IEnumerable<char> 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)
}
输出:
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
这对我来说非常有意义......但是,事实并非如此。
IEnumerable<char> 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)
}
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
哪个不...
有人可以更好地解释一下这里发生了什么吗?
答案 0 :(得分:10)
第一个例子的结果是元音的值被捕获到局部(到for循环的范围)变量。
然后查询的where子句将使用捕获的变量。像这样的where子句使用匿名方法/ lambda方法,它可以捕获局部变量。然后会发生的是它捕获变量的当前值。
但是,在第二个类中,它不捕获当前值,只捕获要使用的变量,因此,由于此变量发生更改,因此每次执行循环时,都会在此基础上构建新的Where子句。最后一个,但是你有点修改所有前面的那个,因为你改变了变量。
因此,在第一个示例中,您将获得此类查询:
IEnumerable<char> 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<char> 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# In Depth: The Beauty of Closures。
如果您将该页面浏览到比较捕获策略:复杂性与功效下的文本,您会发现此行为的一些示例。
答案 1 :(得分:1)
实际上,通过重读它,它是有道理的。 使用temp变量意味着在查询中捕获了temp本身......我们正在评估循环五次,因此每个查询版本都有五个实例化的临时变量引用。
在没有temp变量的情况下,只有对循环变量的引用。
所以五个参考与一个参考。这就是它产生结果的原因。
在第一种情况下,一旦完全评估了循环,查询就使用了对temp变量的五个引用,因此分别剥离了a,e,i,o和u。
在第二种情况下,它正在做同样的事情......只有所有五个引用都属于同一个变量,显然只包含一个值。
故事的道德:认为“参考”而非“价值”。
那么,这对现在的其他人有意义吗?