与以往的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)
{
//
}
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)
{
//
}
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.