GWL*_*osa 4 .net c# linq language-design
采取下面的代码,改编自这个问题:
//Borrowed from another question because its a simpler example of what happened to me.
IEnumerable<char> query = "Not what you might expect";
foreach(char vowel in "aeiou")
{
query = query.Where(c => c != vowel);
}
foreach (char Output in query)
{
System.Out.WriteLine(Output);
}
Run Code Online (Sandbox Code Playgroud)
这只会从查询字符集中删除"u".核心问题与第二个foreach c中的Where子句中的变量未被评估的事实有关.我的问题是:
1)为什么第一个foreach生成的委托不会捕获c构建的每个值?是否有一些情况我不知道哪里不是理想的行为?
2)如果它没有捕获值c,那么当查询实际运行时,该值是否仍然在第二个foreach的范围内?在我看来,如果它没有存储传入的变量的值,那么尝试解析第二个foreach的语句将失败,因为该变量c显然超出了范围.
我不明白为什么'在范围内使用我们在这个变量上看到的最后一个值'对于这种情况是一个很好的设计决策,并且希望有人可以对这个问题有所了解.
它正在捕捉vowel; 尝试:
foreach(char vowel in "aeiou") {
char tmp = vowel;
query = query.Where(c => c != tmp);
}
Run Code Online (Sandbox Code Playgroud)
Jon 在这里有相关帖子的列表.
至于为什么...... foreach被定义为(在ECMA334v4§15.8.4中):
A foreach statement of the form `foreach (V v in x) embedded-statement` is then expanded to:
{
E e = ((C)(x)).GetEnumerator();
try {
V v;
while (e.MoveNext()) {
v = (V)(T)e.Current;
embedded-statement
}
}
finally {
… // Dispose e
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,V就是外面的while-这意味着它捕获只有一次的foreach.据我了解,在C#的团队,有时,怀疑这种变化的智慧(这是内部的while在C#1.2规范,这将完全避免这个问题).也许它最终会改变,但现在它符合规范.
| 归档时间: |
|
| 查看次数: |
239 次 |
| 最近记录: |