为什么C#允许{}代码块没有前面的语句?

为什么C#允许{}代码块没有前面的语句?,c#,syntax,language-design,C#,Syntax,Language Design,为什么C#允许代码块没有前面的语句(例如,if,else,for,while) 在你给出的上下文中,没有意义。在程序流的任何地方,向控制台写入常量字符串的方式都是一样的。1 相反,您通常使用它们来限制某些局部变量的范围。这一点将进一步阐述和讨论。请看和,以获取简短的示例。我相信这同样适用于其他一些具有C风格语法的语言,但这与这个问题无关 1当然,除非您决定尝试变得有趣,并创建自己的Console类,使用Write()方法执行一些完全出乎意料的操作。{…}至少有引入局部变量新范围的副作用 我倾向

为什么C#允许代码块没有前面的语句(例如,
if
else
for
while


在你给出的上下文中,没有意义。在程序流的任何地方,向控制台写入常量字符串的方式都是一样的。1

相反,您通常使用它们来限制某些局部变量的范围。这一点将进一步阐述和讨论。请看和,以获取简短的示例。我相信这同样适用于其他一些具有C风格语法的语言,但这与这个问题无关



1当然,除非您决定尝试变得有趣,并创建自己的
Console
类,使用
Write()
方法执行一些完全出乎意料的操作。

{…}
至少有引入局部变量新范围的副作用

我倾向于在
switch
语句中使用它们,为每种情况提供不同的作用域,这样我就可以在最接近使用它们的位置定义具有相同名称的局部变量,并且还表示它们仅在案例级别有效。

与其说它是C的一个特性,不如说它是一个逻辑副作用在许多使用大括号定义作用域的C语法语言中

在您的示例中,大括号完全没有作用,但在以下代码中,大括号定义了变量的范围,从而定义了变量的可见性:

当i在第一个块中不在范围内,并且在下一个块中再次定义时,允许该

{
    {
        int i = 0;
    }

    {
        int i = 0;
    }
}
是不允许的,因为我已超出范围,并且在外部范围中不再可见:

{
    {
        int i = 0;
    }

    i = 1;
}

我认为<代码> {} /代码>作为一个语句,可以包含多条语句。

考虑一个if语句,它存在于一个布尔表达式之后,后跟一个语句。 这将有助于:

if (true) Console.Write("FooBar");
这也会起作用:

if (true)
{
  Console.Write("Foo");
  Console.Write("Bar");
}
如果我没弄错的话,这叫做块语句

由于
{}
可以包含其他语句,因此它也可以包含其他
{}
。 变量的范围由其父级
{}
(块语句)定义

我试图指出的是,<代码> {} /COD>只是一个语句,所以它不需要if或任何…

,因为C++和java允许没有前面的语句的代码块。 C++允许它们,因为C允许

你可以说,这一切都归结于这样一个事实:美国的程序语言(基于C的)设计胜出,而不是欧洲的程序语言(基于C的)设计


(控制语句作用于单个语句,语句可以分组以创建新语句)

C语法语言中的一般规则是“任何介于
{}
之间的语句都应被视为单个语句,并且可以放在单个语句可以放在的任何地方”:

  • 如果,则在
    之后
  • 之后,当
    执行时
  • 代码中的任意位置
出于所有目的,语言语法包括:

     <statement> :== <definition of valid statement> | "{" <statement-list> "}"
<statement-list> :== <statement> | <statement-list> <statement>
:==|“{”“}”
:==  |  
也就是说,“一个语句可以由(各种事物)或一个大括号组成,后面是一个语句列表(可能包括一个或多个语句),后面是一个大括号”。例如,“一个
{}
块可以在任何地方替换任何语句”。包括在代码的中间。

不允许在单个语句可以到达的任何地方使用
{}
块实际上会使语言定义更加复杂。

因为…它可以维护 陈述或者函数,这对于大型代码来说非常有用

{
    {
        // Here this 'i' is we can use for this scope only and out side of this scope we can't get this 'i' variable.

        int i = 0;
    }

    {
        int i = 0;
    }
}

您问“为什么”C#允许代码块不包含前面的语句。“为什么”这个问题也可以解释为“这种结构可能带来什么好处?”

就我个人而言,我在C#中使用了无语句代码块,这大大提高了其他开发人员的可读性,同时要记住,代码块限制了局部变量的范围。例如,考虑下面的代码片段,由于额外的代码块:

,这更容易阅读。
OrgUnit world = new OrgUnit() { Name = "World" };
{
    OrgUnit europe = new OrgUnit() { Name = "Europe" };
    world.SubUnits.Add(europe);
    {
        OrgUnit germany = new OrgUnit() { Name = "Germany" };
        europe.SubUnits.Add(germany);

        //...etc.
    }
}
//...commit structure to DB here
我知道,通过对每个结构级别使用方法,可以更优雅地解决这个问题。但是,请记住,像样本数据播种器这样的事情通常需要快速进行


因此,尽管上面的代码是线性执行的,但代码结构代表了对象的“真实世界”结构,从而使其他开发人员更容易理解、维护和扩展。

有什么理由不应该这样做吗?但正如答案所示,它不仅仅是“不伤害,所以让我们允许它吧”。问这样的问题很重要。+1个问题听起来很天真,但答案确实教会了我一些东西valuable@Akash:不问为什么,我们永远不会变得更好。@Akash:这似乎是一种高雅的精英主义态度。人们总是有疑问,如果没有理由问为什么,那么这样做就没有意义。这个网站并不是为了让人们解决我们眼前的问题(尽管这确实发生了),而是为了提供一个问题和答案库,帮助我们成为更好的程序员。问为什么也是如此!:-)我读到过不同风格的英语在括号命名法上的差异,但是
{}
被称为括号的是哪种风格?好问题!我想我的导师十年前就把它植入了我的大脑。我可能应该称它们为“花括号”或“大括号”。每个人都有自己的。。。在我的词汇中,“('=括号,“{'=大括号,['=方括号,['=方括号),我将它们称为一个卷曲括号,维基百科包括了这个命名。牛津英语词典将括号的这种用法定义为:
形式[]或()的两个标记中的一个,在数学用法中也是{},用于
{
    {
        // Here this 'i' is we can use for this scope only and out side of this scope we can't get this 'i' variable.

        int i = 0;
    }

    {
        int i = 0;
    }
}
OrgUnit world = new OrgUnit() { Name = "World" };
{
    OrgUnit europe = new OrgUnit() { Name = "Europe" };
    world.SubUnits.Add(europe);
    {
        OrgUnit germany = new OrgUnit() { Name = "Germany" };
        europe.SubUnits.Add(germany);

        //...etc.
    }
}
//...commit structure to DB here