为什么C#需要在条件语句周围加括号?

6
我刚刚在阅读一个有关Python的SO问题时,注意到在for循环中缺少括号。这看起来很好,然后我想知道:为什么C#需要它们呢?
例如,目前我需要写成这样:
if (thing == stuff) {
}

并且

foreach (var beyonce in allthesingleladies) {
}

所以我想知道为什么我不能写:
if thing == stuff {
}

那个陈述句中是否存在我不知道的句法歧义?
顺便说一句,有趣的是,大括号在单行代码中可以省略。
if (thing == stuff)
  dostuff();

我会 Obj-C 和 PHP,有时候你也不必使用 if。:p 这只是我的个人看法。 - Thomas Clayson
@Ardman - OP指的是()而不是{},但PS确实让事情变得混乱了。 - ChrisF
@Ardman:需要明确的是,只有在if后包含多个语句时才需要使用大括号(单个语句可以跨越多行)。 - Robert Harvey
6个回答

8
系统需要某种方式来确定条件何时停止,语句何时开始。这意味着条件周围的括号是可选的,或者是语句周围的大括号是可选的。C# 的设计者选择使大括号是可选的(如果只有一个语句的情况下)。
考虑以下内容:
if x == 12 - x == 3 ? x++ : x--;

可以编写一个解析器来确定条件结束和语句开始的位置,但是要求使用括号会使其更加简单。在我的示例中,语法表明完整语句为if (x == 12) { -x == 3 ? x++ : x--; }。然而,直到第二个==出现时,你才知道-是语句的开头,这已经是三个标记了。
由于正确解析这样的示例需要从输入流中任意查看多个标记(并且可以说这使得人们难以阅读代码),因此有很好的理由要求使用括号。

你说的没错,但根据BNF规范,“then”从句中总是只有一个语句。关键在于它可以是复合语句,在花括号之间包含若干语句。 - Steven Sudit
这是正确的。然而,它仍然没有回答为什么不可以省略任何一个,只要不省略两个。OP的最后两个例子都不含糊 - 为什么只允许其中一个?(更多地作为修辞问题提出...) - Tomas Aschan
啊,好主意。我以为花括号只是一个有趣的小知识点,但是你说得对,你不能既有可选的花括号又有可选的圆括号。 - Matt Sherman
如果下一条语句之前有其他分隔符(如“Then”),则可以选择使用可选的大括号和括号。某些运算符存在一元和二元形式确实允许一些示例真正具有歧义。例如,“if x+y==3 && foo() +z==4 && bar();”可以评估为“if (((x+y)==3) && foo()) (+z==4 && bar());”或者“if (x) ((+y==3) && ((foo()+z)==4) && (bar()));”。具有不同的执行语义。 - supercat

4

这是一种语法“特性”,可以追溯到C语言,甚至可能是更早的某些语言。

本质上,这是在两者之间做出选择:

if (condition) statement;

并且。
if condition then statement;

在C语言诞生的时候,简洁的符号和少量的关键词是潮流。

历史上的编程语言演变顺序为CPL -> BCPL -> B -> C -> C++。CPL具有“if条件则”语法。BCPL具有“if条件执行”语法,但仍然没有括号。B已经类似于C。 - Jirka Hanika

2

[我知道我可能会因此受到责备,但我还是必须说出来]

作为一个主要使用vb编程的人,有一件事情让我非常烦恼。在我看来,括号应该是可选的,而大括号则是必须的。如果这太难要求了,那么微软可以通过引入c#的Then的等效物来借鉴vb。

但是,为什么要费劲呢?微软基于C、C++和Java设计了C#,它们都将if条件放在括号中,那么为什么C#要与它们不同呢?


编辑

老实说,我认为基于C# 4的“可选参数和命名参数的采用,这是VB中一直存在的特性(至少从VB6开始),C#的下一个版本(即C# 5.0)也可以引入一个'新'功能,这样您就不必键入不必要的括号了。

由于有三元if condition ? truePart : falsePart,所以有if condition then something或对于那些不想让C#看起来像vb的人,if condition do something也不是一个坏主意。


1
作为一名曾经的VB程序员,我也会觉得括号(以及花括号)很烦人。但是作为一名改过自新的C#程序员,我发现对我来说,括号和圆括号使代码更易读,因为它们在视觉上起到了栅栏的作用(括号和花括号在视觉上与单词有所不同)。今天我发现阅读VB很不舒服,但我想这归结于你习惯于什么(或者可能是当前正在使用的语言)。 - Robert Harvey
我同意标点符号使阅读更容易。使用单词作为标点符号的语言(如COBOL或VB)更难阅读。 - Gabe
3
VB也有括号和Then关键字。使用标点符号代替关键字只是一种风格偏好。 - Hans Passant
@Hans:如果在VB中不必要地使用括号被认为是不好的风格,那也不会让我感到惊讶。 - Robert Harvey
1
@Alex:是的,C#开发人员世界范围内都能立即识别出标识符末尾的空括号表示调用方法(而不是属性、变量或其他成员)。这是一个非常重要的信息,当阅读代码时具有可视化指示器可以非常有价值。此外,在C#中只有一种方式可以调用方法(使用括号);这可以说使语言(以及无需摩擦地阅读它的能力)更加一致。 - Robert Harvey
显示剩余2条评论

0

这是一种语言设计选择,源自Java,而Java又源自C++,C++又源自C,C又源自哪里呢?

Python不需要花括号,因为缩进可以显示意图。F#也是如此。我认为这是一个好主意。


Python需要使用冒号来表示所包含语句的开始;F#则使用dothen - Gabe

0

顺便说一句,如果我可以自己选择的话,我会允许一个运算符在括号外面:一个前置感叹号。令我不爽的是,测试复杂的负条件的代码最终需要比测试复杂的正条件的代码多一个括号。


我同意,if! 是一个简便的说“unless”的方式。 - Gabe

0
简单来说,这是由于C/C++/C#如何处理空格的原因。由于语句可以跨越多行,所以需要一种分隔符。您还需要一种将语句“阻塞”或分组到一个块中的方法。
  • C/C++/C#使用()和{}
  • VB/VB.NET/VBScript/VBA使用Function/End Function、Sub/End Sub、If/Then/Else/Else If/End If等(仅用于阻止,因为基于VB的语言不支持跨越多行的语句)。

如果您的具体问题是,您正在使用()创建表达式。因此,您需要一种告诉编译器您已完成表达式的方法,因为{}(阻止分隔符)不是必需的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接