C#变量范围';x';无法在此范围中声明,因为它将赋予';x';
这将导致: 错误1名为“var”的局部变量 无法在此作用域中声明 因为它会给人一种不同的感觉 对“var”的含义,已经是 在“子”范围中用于表示 还有别的 真的没有什么惊天动地的,但这不是完全错了吗?我和一位开发人员同事想知道第一个声明是否应该在不同的范围内,因此第二个声明不能干扰第一个声明 为什么C#无法区分这两个范围?第一个IF范围是否应该与方法的其余部分完全分开C#变量范围';x';无法在此范围中声明,因为它将赋予';x';,c#,scope,C#,Scope,这将导致: 错误1名为“var”的局部变量 无法在此作用域中声明 因为它会给人一种不同的感觉 对“var”的含义,已经是 在“子”范围中用于表示 还有别的 真的没有什么惊天动地的,但这不是完全错了吗?我和一位开发人员同事想知道第一个声明是否应该在不同的范围内,因此第二个声明不能干扰第一个声明 为什么C#无法区分这两个范围?第一个IF范围是否应该与方法的其余部分完全分开 我无法从if外部调用var,因此错误消息是错误的,因为第一个var与第二个范围无关。这里的问题主要是良好实践和防止意外错误。诚然
我无法从if外部调用var,因此错误消息是错误的,因为第一个var与第二个范围无关。这里的问题主要是良好实践和防止意外错误。诚然,C#编译器在理论上可以设计为在这里范围之间没有冲突。然而,在我看来,这将是一个事半功倍的过程 考虑一下,如果父范围中
var
的声明在if语句之前,则会出现无法解决的命名冲突。编译器只是不区分以下两种情况。分析完全基于范围,而不是您所期望的声明/使用顺序
理论上可以接受(但就C#而言仍然无效):
和不可接受的(因为它将隐藏父变量):
在变量和作用域方面,两者被完全相同地对待
现在,在这篇文章中,有什么实际的原因不能给其中一个变量起一个不同的名字吗?我假设(希望)您的实际变量不被称为var
,所以我并不认为这是一个问题。如果仍然打算重用相同的变量名,只需将它们放在同级作用域中:
string var = "New VAR!";
if(true)
{
string var = "VAR";
}
但是,这对编译器来说是有效的,在读取代码时会导致一些混乱,所以我建议在几乎任何情况下都反对它。
< P>这在C++中是有效的,但对于许多bug和不眠之夜来说是一个来源。我认为C#伙计们决定最好抛出一个警告/错误,因为在绝大多数情况下,它是一个bug,而不是程序员真正想要的东西 关于这个错误来自规范的哪些部分,有一个有趣的讨论 编辑(一些示例)----- <>在C++中,下面的方法是有效的(并且,如果外部声明在内部范围之前或之后并不重要,它将更有趣,而且如果以前是错误的话)。void foo(int a)
{
整数计数=0;
对于(int i=0;i
现在假设函数长几行,可能很容易发现错误。编译器从不抱怨(以前不是这样,不确定C++的新版本),函数总是返回0
该行为显然是一个bug,因此如果c++-lint程序或编译器指出这一点就好了。如果不是bug,只需重命名内部变量即可轻松解决
雪上加霜的是,我记得GCC和VS6对for循环中的反变量的归属有不同的看法。一个说它属于外部范围,另一个说它不属于外部范围。处理跨平台代码有点烦人。让我再举一个例子,让我的队伍不断壮大
void foo(int a)
{
int count = 0;
for(int i = 0; i < a; ++i)
{
int count *= i;
}
return count;
}
for(int i=0;i<1000;++i)
{
if(数组[i]>100)
打破
}
printf(“数组中第一个非常大的值存在于%d\n”,i);
这段代码在VS6 IIRC中工作,而不是在GCC中。无论如何,C#已经清理了一些东西,这很好
这难道不是大错特错吗
不,这完全没有错。这是C#规范第7.5.2.1节“简单名称,块中不变含义”的正确实现
该规范规定:
对于给定事件的每次出现 标识符,作为 表达式或声明器,在 局部变量声明空间 在那次事件中,每 同一事件的其他发生 标识符,作为 表达式或声明符必须引用相同的 实体。这条规则确保 名字的意思总是一样的 在给定的块内,开关块, for-、foreach-或using语句,或 匿名函数
为什么C#无法区分这两个范围 这个问题是荒谬的;显然,编译器能够区分这两个作用域。如果编译器无法区分这两个作用域,那么如何产生错误?错误消息说有两个不同的作用域,因此作用域已被区分 第一个IF范围是否应该与方法的其余部分完全分开 不,不应该。由块语句在条件语句的结果中定义的范围(和局部变量声明空间)在词汇上是定义方法体的外部块的一部分。因此,关于外部块内容的规则适用于内部块的内容 我不能从if外部调用var, 所以错误信息是错误的,因为 第一个风险值与第二个风险值无关 第二个范围 这是完全错误的。仅仅因为局部变量不再在作用域中,外部块不包含错误的结论是似是而非的。错误消息是正确的 这里的错误与任何变量的范围是否与任何其他变量的范围重叠无关;这里唯一相关的是,在wh中有一个块——外部块
string var = "New VAR!";
if(true)
{
string var = "VAR";
}
if(true)
{
string var = "VAR";
}
{
string var = "New VAR!";
}
void foo(int a)
{
int count = 0;
for(int i = 0; i < a; ++i)
{
int count *= i;
}
return count;
}
for(int i = 0; i < 1000; ++i)
{
if(array[i] > 100)
break;
}
printf("The first very large value in the array exists at %d\n", i);
class C
{
int x;
void M()
{
int x = 123;
}
}
class C
{
int x;
void M()
{
Console.WriteLine(x);
if (whatever)
{
int x = 123;
}
}
}
class C
{
int x;
void M()
{
if (whatever)
{
Console.WriteLine(x);
}
if (somethingelse)
{
int x = 123;
}
}
}