與以往的C,C++相比,C#引入了foreach語句,確實讓很多完成迴圈邏輯的代碼簡潔了不少。但是今天在寫代碼的時候卻又讓我感覺到C#在foreach文法上還有不夠理想的地方:
/**//*
I declared a variable named 'row' and used it before the foreach iteration.
*/
DataRow row;
//
/**//* And here I still wanna use variable 'row' to represent each row in the table row collection. However, this is not allowed in C#, and will lead to a compilation error which says the variable has already been delcared in the parent scope:(
*/
foreach (DataRow row in table.Rows)
{
//
}
翻閱了一下MSDN中的C# Programmer's Reference章節,關於foreach, in語句的定義如下:
foreach (type identifier in expression) statement
where:
-
type
-
The type of
identifier.
-
identifier
-
The iteration variable that represents the collection element. If the iteration variable is a value type, it is effectively a read-only variable that cannot be modified.
-
expression
-
Object collection or array expression. The type of the collection element must be convertible to the
identifier type. Do not use an expression that evaluates to
null.
Evaluates to a type that implements IEnumerable or a type that declares a GetEnumerator method. In the latter case, GetEnumerator should either return a type that implements IEnumerator or declares all the methods defined in IEnumerator.
-
statement
-
The embedded statement(s) to be executed.
從文法上來看identifier前面必須要有type的聲明,雖然這裡的文檔沒有明確強調,但是事實上C#編譯器會要求的,如果沒有類型的聲明將會報錯。這就帶來一個問題:就是foreach語句中用來枚舉集合中元素的那個變數必須是一個新的變數聲明,因為在表識符的前面必須要有類型。所以如果想要用前面已經聲明的變數的話就不可能了。因此個人覺得這個是目前C#語言的一個缺陷,或者是不夠合理的地方,不知道C#2.0有沒有改進?
為什麼我覺得不夠合理?讓我們再來看一下VB.NET中的for each語句的文法,那裡就允許使用前面已經聲明過的變數:
For Each element [ As datatype ] In group [ statements ][ Exit For ] [ statements ]Next [ element ]
Parts
-
element
-
Required. Variable. Used to iterate through the elements of the collection. The data type of
element must be such that the data type of the elements of
group can be converted to it.
-
datatype
-
Required if
element is not already declared. Data type of
element. If
element is declared outside this loop, you cannot use the
As clause to redeclare it.
-
group
-
Required. Object variable. Must refer to an object collection or array.
-
statements
-
Optional. One or more statements between
For Each and
Next that are executed on each item in
group.