我有两个代码循环的代码片段,后者按预期工作,而前者抛出异常。为什么foreach
工作而for
循环不工作?到底是什么原因?
IEnumerable<char> query = "Not what you might expect";
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');
foreach (char c in query) Console.Write (c); // Nt wht y mght xpct
有异常的循环
IEnumerable<char> query = "Not what you might expect";
string vowels = "aeiou";
for (int i = 0; i < vowels.Length; i++)
query = query.Where (c => c != vowels[i]);
foreach (char c in query) Console.Write (c);
foreach
代码,
foreach (char vowel in vowels)
query = query.Where (c => c != vowel);
foreach (char c in query) Console.Write (c);
答案 0 :(得分:2)
好吧, Linq 使用 lazy (延迟执行),所以您有:
// Just a declaration, query doesn't execute
for (int i = 0; i < vowels.Length; i++)
query = query.Where (c => c != vowels[i]);
// now, after the for loop, i is equal to vowels.Length
// Here, query executes with current i value, i == vowels.Length
// And you have an out of range exception
foreach (char c in query) Console.Write (c);
答案 1 :(得分:1)
for
循环捕获i
变量,为避免这种情况,您必须编写类似的内容
for (int i = 0; i < vowels.Length; i++)
{
int index = i;
query = query.Where(c => c != vowels[index]);
}
否则,在此行的查询执行期间
foreach (char c in query) Console.Write (c);
捕获的i
变量的值将等于vowels.Length
,并导致索引超出范围异常。发生这种情况是因为documentation
Linq
使用了延迟执行
立即返回值是一个存储所有 执行操作所需的信息。查询 直到对象为 通过直接调用其GetEnumerator方法或通过枚举来枚举 在Visual C#中使用foreach
在您的情况下,直接返回值为Linq
查询,该查询捕获循环变量i
。创建查询后(在其内部调用foreach
方法的情况下,在GetEnumerator
循环中遍历对象时会枚举对象。在执行过程中,查询使用捕获的等于5的循环变量。
foreach片段中没有捕获到的循环变量,它工作正常
foreach (char vowel in vowels)
query = query.Where (c => c != vowel);