我刚学linq,遇到点问题,希望高手解答。下面是我用linqpad中的例子的疑问。
IEnumerable<char> query = "期望中的结果";
query = query.Where (c => c != 'a');
query = query.Where (c => c != 'e');
query = query.Where (c => c != 'i');
query = query.Where (c => c != 'o');
query = query.Where (c => c != 'u');
new string (query.ToArray()).Dump ("所有元音都被过滤.");
query = "不是期望的结果";
foreach (char vowel in "aeiou")
query = query.Where (c => c != vowel);
new string (query.ToArray()).Dump ("只有u被过滤了");
不知道延迟查询是怎么回事,我知道ToList()可以取消延迟查询。而且在foreach里添加一个变量替换vowel也可以和第一个显示的一样,这是为什么呢?不清楚究竟为什么两个结果不一样?坐等高手!
因为vowel定义在循环之外,所以每个foreach中的每一个lambda表达式都捕获了同一变量。当我们的query执行时,vowel的值是什么呢?不正是被过滤的字母u嘛。要解决这个问题,我们只需把循环变量赋值给一个内部变量即可,如下面的temp变量作用域只是当前的lambda表达式。
foreach (char vowel in "aeiou")
{
char temp = vowel;
query = query.Where(c => c != temp);
}
我的博客http://www.cnblogs.com/lifepoem/archive/2011/10/29/2228589.html正好讨论了该问题。
万分感谢,这个问题困惑了我好久,终于解决了。
这个应该是作用与的关系,与延迟加载没有关系。这个就是一个闭包,作用域是与上下文相关的,你下面的foreach就相当于只是过滤了'U'
而你使用一个变量就是将这个vowel 的作用域缩小到一个循环体内