这个问题在这里已有答案:
我使用C#foreach循环遇到了一个奇怪的问题,我不明白为什么 . 有人可以解释一下这段代码有什么问题吗?
var previouslyLoadedControls = ComposantPanel.Controls.OfType<GridView>().Where(x => x.Rows.Count > 0);
foreach (var gridView in previouslyLoadedControls)
{
gridView.DataSource = null;
gridView.DataBind();
}
var gridViewId = "GridViewOne";
var gridView = (GridView)ComposantPanel.FindControl(gridViewId);
gridView.DataSource = objects;
gridView.DataBind();
gridView.Visible = true;
编译器告诉我“一个名为'gridView'的局部变量不能在这个范围内声明,因为它会给'gridView'赋予不同的含义,'gridView'已经在'子'范围内用来表示其他东西”at line“var gridView = (GridView的)ComposantPanel.FindControl(gridViewId);”
为什么不能在foreach循环范围中访问第一个gridView变量?
如果我只是将第二个gridView声明注释掉,那么编译器会告诉我“gridView.DataSource = objects;”中的“当前上下文中不存在名称'gridView'” . 那个foreach变量的范围是什么?
我开始阅读关于闭合的一些arciles(http://ericlippert.com/2009/11/12/closing-over-the-loop-variable-considered-harmful-part-one/和http://csharpindepth.com/Articles/Chapter5/Closures.aspx),但我仍然没有得到它 .
我使用VS 2013与.Net 4.5.1和C#5 .
2 回答
它是,但编译器(语言定义)只是禁止重叠范围 .
产生相同错误的简化版本:
这很难读取get的原因是第二个'i'只能在声明之后使用,但它的作用域是整个外部块 .
见C# Language specification, § 3.7: Scopes
你提到读过的文章在这里是无关紧要的,因为你没有对循环变量进行闭包 .
会发生什么是在封闭范围内有一个同名变量 . 这是不允许的(至少对于从方法开始的范围) . 如果您尝试在
for
循环中声明gridView
或只是嵌套块,则会遇到同样的问题 .但是,您可以使用相同的变量名称将两个循环彼此相邻,因为它们不会重叠 . 另请注意,变量范围由块确定,即使您只能在声明它们之后才能访问它们 . 这意味着即使您的
foreach
循环在声明第二个gridView
变量之前,它们的范围也会重叠 .