C# Can’;t在条件语句中声明局部变量

C# Can’;t在条件语句中声明局部变量,c#,.net,C#,.net,这是允许的: // scope_1 int i = 100; if (i > 50) { // scope_2 int a = 200; } 这会产生以下错误: // scope_1 if (100 > 50) int a = 200; 第二个代码示例给出的错误是由于作用域引起的吗?因此,编译器不允

这是允许的:

        // scope_1
        int i = 100;
        if (i > 50)
        {
            // scope_2
            int a = 200;
        }
这会产生以下错误:

        // scope_1
        if (100 > 50)
            int a = 200;

第二个代码示例给出的错误是由于作用域引起的吗?因此,编译器不允许仅当条件语句的计算结果为true时才声明特定范围内的变量a,因为如果它允许,编译器将无法确定是否允许在范围1内声明另一个名为a的变量

if
语句中不使用括号,因此此后只允许使用一条语句。如果变量不可能被引用,那么标注变量的尺寸又有什么意义呢

另外,您的第二个
if
语句使用文字常量,显然永远不会为真。再说一遍,在里面放东西有什么意义


也许我误解了你的问题。

因为你将无法从{}端访问它。如果编译器允许您这样做,变量的作用域

a

将仅限于支架

        // scope_1
        int i = 100;
        if (i > 50)
        {
            // scope_2
            int a = 200;
        }

        // if you will try
        int anotherA = a; // a does not exist in the current context
你为什么要这么做?在语句为变量的单语句范围内声明变量似乎没有意义,因为您根本没有时间使用声明的变量


如果允许在
if
语句之外引用
a
,则上述操作将导致条件变量声明。但是,声明不能是有条件的。当编译器遇到可以声明或未声明的标识符时,它可以合理地做什么?无论哪种情况,都只能在运行时计算出来,而不能在编译时计算出来;但是,编译器需要知道(因为未声明的标识符是一个语法错误),因此它会抱怨这个构造。

看看第二种情况:

if (100 > 50)
    int a = 200;
您声明的变量“a”只能在该语句中使用。但是,它是一个l值,因此定义变量的全部目的是在以后使用它

你不能这样做(原因很明显):

if(100>50)
INTA=200;
控制台。写入线(a);//这毫无意义。。。如果100<50会发生什么????

编译器非常聪明,可以在这个实例中出错,因为如果允许的话,你根本不可能使用这个变量。

第二个作用域是为只包含一条指令而创建的,因此声明一个变量(已经是一条指令)是没有用的,因为它只能在那个作用域中使用

编译器从来没有错

看一看

对于国际单项体育联合会来说,这不是强制性的 语句,以便在需要时使用{} 将其范围限制为仅一行。 但是,我们不能有一个变量 声明为后面的唯一行 信息技术这是因为如果条件 如果结果为false,则变量将 永远不要被创造

也看看

一种嵌入的语句,它不是 用{}括号括起来的不能是 声明语句或标签 声明


这与编译器的“范围”以及
a
是否在
if
之外可见无关

C89标准不允许这两种构造。在C99中,允许在块(复合语句)的开头声明变量,而不允许在其他地方声明变量

此代码没有块:

 if ( i )
   int a = 100;
它也没有隐含的块——这可能就是你所想的。“if”后面可以跟一个语句或复合语句。复合语句是允许您拥有声明列表的地方。上面这件事只是一个陈述

可以通过添加{}将其转换为复合语句

if(
expression
语句

Where语句可以是单个语句,也可以是复合语句

复合语句:
{
声明列表语句列表}

(另见K&R 2ed A9.3“复合报表”)

如前所述,这是一个C#问题。C#标准在第15.2节中对此进行了阐述,但不够简洁:基本上,声明需要一个块。积木需要支撑。故事结束。

您得到的错误是:

error CS1023: Embedded statement cannot be a declaration or labeled statement
这意味着if语句的语法要求在条件表达式之后有一个语句或语句块


声明不是语句,所以它只是一个简单的语法错误。

让我重新表述一下您的问题

规范的哪一部分定义了这种行为

第8.7.1节规定,“如果”的声明为“嵌入声明”

第8节开头指出,嵌入语句可以是块语句或空语句、表达式语句、选择语句、迭代语句、跳转语句、尝试语句、选中语句、未选中语句、锁定语句、使用语句或产生语句,但不能是带标签的语句或声明语句

为什么不允许声明声明

最初的语言注释没有提到这一点,但我们可以做出一些有根据的猜测。你的猜测很好;这样做会使我们很难对所声明的本地数据的范围进行推理。如果允许,则必须确定“If”是否隐式创建局部变量声明范围,即使没有块:

if (x) int y = M();
else string y = N();
这是重新声明的局部变量错误吗?或者条件的每个分支都会产生自己的局部变量声明空间吗

这个怎么样

if(x) int y = M();
else y = N();
Q(y);
y在范围内是否超出后果范围?如果是的话,当它到达Q(y)时,它是否确实被赋值

我没有很强的直觉来判断这里应该做什么。不管我们选哪一个,似乎有一半的人会认为我们选错了。如果您想引入一个新的局部变量声明空间,那么最好将整个过程视为非法,并使用大括号

还有一些你没问的问题:

swi呢
if-stmt -> 'if' '(' expr ')' stmt ['else' stmt]  

stmt ->    if-stmt
     ->    do-stmt
     ->    ...etc...
     ->    '{' [declaration...] [stmt...] '}'
if (x) int y = M();
else string y = N();
if(x) int y = M();
else y = N();
Q(y);