|
此文章由 yangwulong1978 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 yangwulong1978 所有!转贴必须注明作者、出处和本声明,并保持内容完整
我刚查了查书。
错误
// Suppose we want to build up a query that strips all the vowels from a string.
// The following (although inefficient) gives the correct result:
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');
new string (query.ToArray()).Dump ("All vowels are stripped, as you'd expect.");
"Now, let's refactor this. First, with a for-loop:".Dump();
string vowels = "aeiou";
for (int i = 0; i < vowels.Length; i++)
query = query.Where (c => c != vowels[i]); // IndexOutOfRangeException
foreach (char c in query) Console.Write (c);
// An IndexOutOfRangeException is thrown! This is because, as we saw in Chapter 4
// (see "Capturing Outer Variables"), the compiler scopes the iteration variable
// in the for loop as if it was declared outside the loop. Hence each closure captures
// the same variable (i) whose value is 5 when the query is enumerated.
解决方案。
// We can make the preceding query work correctly by assigning the loop variable to another
// variable declared inside the statement block:
IEnumerable<char> query = "Not what you might expect";
string vowels = "aeiou";
for (int i = 0; i < vowels.Length; i++)
{
char vowel = vowels[i];
query = query.Where (c => c != vowel);
}
foreach (char c in query) Console.Write (c);
FOREACH 在 C#3,4 里也是同样的错误,5 里就FIX了,,
// Let's now see what happens when you capture the iteration variable of a foreach loop:
IEnumerable<char> query = "Not what you might expect";
string vowels = "aeiou";
foreach (char vowel in vowels)
query = query.Where (c => c != vowel);
foreach (char c in query) Console.Write (c);
// The output depends on which version of C# you're running! In C# 4.0 and C# 3.0, we
// get the same problem we had with the for-loop: each loop iteration captures the same
// variable, whose final value is 'u'. Hence only the 'u' is stripped. The workaround
// for this is to use a temporary variable (see next example).
// In C# 5.0, they fixed the compiler so that the iteration variable of a foreach loop
// is treated as *local* to each loop iteration. Hence our example strips all vowels
// as expected. |
|