为什么C#允许没有前面语句的代码块(例如if
,else
,for
,while
)?
void Main()
{
{ // any sense in this?
Console.Write("foo");
}
}
答案 0 :(得分:141)
{ ... }
至少具有为局部变量引入新范围的副作用。
我倾向于在switch
语句中使用它们为每种情况提供不同的范围,这样我就可以在最近的使用位置定义具有相同名称的局部变量,并且也表示它们仅在案件级别有效。
答案 1 :(得分:87)
在你给出的上下文中,没有任何意义。将一个常量字符串写入控制台将在程序流程的任何地方以相同的方式工作。 1
相反,您通常使用它们来限制某些局部变量的范围。这进一步阐述了here和here。请查看João Angelo’s answer和Chris Wallis’s answer以获取简要示例。我相信这同样适用于其他一些具有C风格语法的语言,但并不是说它们与这个问题有关。
1 当然,除非你决定尝试搞笑并创建自己的Console
课程,使用Write()
方法做一些完全出乎意料的事情子>
答案 2 :(得分:55)
它不是C#的功能,而是使用大括号定义范围的许多C语法语言的逻辑副作用。
在您的示例中,大括号根本没有效果,但在以下代码中,它们定义变量的范围,从而定义可见性:
允许 ,因为我在第一个区块中超出了范围,并在下一个区域再次定义:
{
{
int i = 0;
}
{
int i = 0;
}
}
不允许 ,因为我已超出范围且在外部范围内不再可见:
{
{
int i = 0;
}
i = 1;
}
依旧等等。
答案 3 :(得分:17)
我认为{}
是一个可以包含多个语句的语句。
考虑一个if语句,它存在于布尔表达式后面跟着一个语句。 这可行:
if (true) Console.Write("FooBar");
这也可行:
if (true)
{
Console.Write("Foo");
Console.Write("Bar");
}
如果我没有弄错,这称为块声明。
由于{}
可以包含其他语句,因此它还可以包含其他{}
。
变量的范围由它的父{}
(块语句)定义。
我想说的是{}
只是一个陈述,所以它不需要if或者其他......
答案 4 :(得分:11)
C语法语言中的一般规则是“{ }
之间的任何内容都应被视为单个语句,并且它可以在单个语句可以”的任何地方“:
if
之后。for
,while
或do
。对于所有意图和目的,它都包含在语言语法中:
<statement> :== <definition of valid statement> | "{" <statement-list> "}"
<statement-list> :== <statement> | <statement-list> <statement>
也就是说,“一个语句可以由(各种各样的东西)或一个左括号组成,后跟一个语句列表(可能包含一个或多个语句),然后是一个闭括号”。 I.E. “{ }
块可以在任何地方替换任何语句”。包括在代码中间。
单个语句可以在任何地方不允许{ }
块实际上会使语言定义更复杂。
答案 5 :(得分:1)
因为C ++(和java)允许没有前面语句的代码块。
C ++允许他们,因为C。
你可以说这一切都归结为美国程序语言(基于C语言)设计赢得而不是欧洲程序语言(基于Modula-2)设计。
(控制语句作用于单个语句,语句可以是组来创建新语句)
答案 6 :(得分:1)
// if (a == b)
// if (a != b)
{
// do something
}
答案 7 :(得分:0)
1因为...它保持了范围 声明..或函数,这对于大型代码鬃毛非常有用..
{
{
// 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;
}
}
答案 8 :(得分: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
我知道通过使用每个结构级别的方法可以更优雅地解决这个问题。但话说回过来,请记住样本数据播种机之类的东西通常需要很快。
因此,即使上面的代码是线性执行的,代码结构也代表了对象的“真实世界”结构,从而使其他开发人员更容易理解,维护和扩展。