为什么C#开发人员用换行符括起来?[关闭]


44

在过去的几年中,我大部分时间主要用于C#和SQL。在那段时间里,与我合作的每个程序员都习惯将函数或控制流语句的左括号放在新的一行上。所以...

public void MyFunction(string myArgument)
{
     //do stuff
}

if(myBoolean == true)
{
    //do something
}
else
{
    //do something else
}

我一直对这是多么浪费空间感到震惊,尤其是在if / else语句中。而且我知道在C#的更高版本中存在替代方法,例如:

if(myBoolean == true)
    //do something on one line of code

但是几乎没有人使用过它们。每个人都在做换行符。

缺席很久之后,我又重新开始使用JavaScript。在我的记忆中,JavaScript开发人员曾经做过完全相同的curl-brace-newline事情,但是对于所有花哨的新库和新东西,大多数开发人员都在声明后加上了大括号:

function MyJavaScriptFunction() {
    //do something
}

您可以从中看到这种感觉,因为自从使用闭包和函数指针在JavaScript中变得很流行以来,它就节省了大量空间并提高了可读性。所以我想知道为什么它在C#中没有被视为完成的事情。实际上,如果您在Visual Studio 2013中尝试上述构造,它实际上会为您重新格式化,将开括号放在新的一行上!

现在,我在Code Review SE上看到了这个问题:https : //codereview.stackexchange.com/questions/48035/questions-responses-let-me-tell-you-about-you 在Java中,我了解到我不太熟悉的一种语言,在声明后立即以现代JavaScript格式打开花括号被认为是不当的。

我一直都知道C#最初是按照Java建模的,并且遵循许多相同的基础编码标准。但是在这种情况下,似乎没有。因此,我认为一定有一个很好的理由:原因是什么?为什么C#开发人员(和Visual Studio)在新行上强制使用大括号?


30
约定就是这样。
Oded 2014年

19
Visual Studio不执行任何操作,代码样式是可配置的。某些内容需要为默认值。默认为“更好”的是最高级别的骑车前来。
Phoshi 2014年

23
该行末尾的括号是古老的K&R C标准。当计算机显示器只有25行(如果添加标题行和状态行为23行)时,Kernighan和Ritchie发明了C语言。真的不再是这种情况了吧?重要的是整个项目的一致性。还显示,在其自己的行括号(缩进到同一级别的代码,实际上)提高了代码的科学研究理解,尽管人们认为他们思考的美学。
Craig

10
顺便说一句,C#始终支持在条件之后评估一行代码。实际上,即使是现在,这也是唯一的操作。将代码放在分支表达式之后的花括号中只会使该指令成为goto(编译器使用jmp指令创建作用域)。在大多数情况下,C ++,Java,C#和JavaScript或多或少都基于C,并且具有相同的基础解析规则。因此,从这个意义上讲,C#并非“基于Java”。
克雷格

10
作为旁注,if(myBoolean == true)对我来说毫无意义。当我们在这里时,不是if ((myBoolean == true) == true)吗?仅if (myBoolean)此而已。对不起,我的宠儿。
Konrad Morawski 2014年

Answers:


67

该行末尾的括号是古老的K&R C标准,出自Brian Kernighan和Dennis Ritchie的《The C Programming Language》一书,他们在共同发明UNIX操作系统和C编程语言后于1978年出版(我认为C是主要由Ritchie设计),在AT&T。

曾经有过关于“一种真正的支撑风格”的大战。

Ritchie发明了C语言,而Kernighan编写了第一个教程,当时计算机显示器仅显示几行文本。实际上,UNICS(后来的UNIX)开发是从DEC PDP-7开始的,它使用打字机,打印机和纸带作为用户界面。UNIX和C在带有24行文本终端的PDP-11上完成。因此,垂直空间确实非常宝贵。我们今天的显示器和分辨率更高的打印机都稍微好一点,对吗?我的意思是,我不了解您,但是现在我面前有三(3)个24英寸1080p显示器。:-)

而且,这本小书《 C编程语言》中大部分都是代码示例,这些代码示例将花括号放在行尾而不是放在自己的行上,据称节省了可观的印刷成本。

真正重要的是整个项目或至少在给定的源代码文件中的一致性

还显示,在其自己的行括号(缩进到同一级别的代码,实际上)提高了代码的理解,尽管人们认为他们思考美学的科学研究。它使读者从视觉和直觉上清楚地知道哪些代码在哪种上下文中运行。

if( true )
    {
    // do some stuff
    }

顺便说一句,C#一直支持在分支表达式之后评估单个命令。实际上,即使是现在,这也是唯一的操作。将代码放在分支表达式之后的花括号中只会使该命令成为goto(编译器使用jmp指令创建作用域)。在大多数情况下,C ++,Java,C#和JavaScript或多或少都基于C,并且具有相同的基础解析规则。因此,从这个意义上讲,C#并非“基于Java”。

总结一下,这一个宗教/烈火之战的问题。但是,研究使得它很清楚,在块安排代码改善人类的理解。编译器不在乎。但这也与为什么我从来没有在大括号后的分支后放一行代码的原因有关-对于我或另一个程序员来说,稍后再在其中添加另一行代码实在太容易了,而忽略了这样的事实:在同一上下文中,在该行之前或之后执行该行。

编辑只需查看一下Apple goto failbug,就可以找到此确切问题的完美示例,它对现实世界造成了非常严重的后果。

if( true )
    doSomething();

变成...

if( true )
    doSomething();
    doSomethingElse();

在这种情况下,doSomethingElse()无论测试结果如何,每次都会执行,但是由于它缩进到与doSomething()语句相同的级别,因此很容易遗漏。这并不是真正的争论。对此进行研究。这是维护期间引入到源代码中的错误的重要来源。

尽管如此,我还是承认JavaScript闭包语法看起来有点愚蠢,在自己的行上用大括号...从美学上讲。:-)


13
关于条件块的部分会引起误解。在C语言中,条件语句始终只有一个语句,而块(又称复合语句)是一种语句。C#遵循了这一先例。无论如何,由于所有通用指令集的线性性质,条件评估始终意味着某种条件的goto或分支指令。没有障碍的条件与有障碍的条件在质量上没有什么不同(关于范围的除外)。
天宫院

3
@Craig,请记住,那是在贝尔实验室的,那是在贝尔实验室被特许做“做有趣的事情”的时候,而这并不一定要对任何事情都是实用的。将聪明的人放在建筑物上,告诉他们做一些有趣的研究,将他们从做的事情中移出并不“有趣”,有趣的是,有趣的东西(例如晶体管和Unix)会突然冒出来。DARPA从一开始就具有相同的重点,他们以基础研究的名义资助了很多出色的工作。
John R. Strohm 2014年

3
@克雷格:在过去的Pascal / Delphi时代,我通常避免在单行代码块中使用它,因为Pascal使用beginend代替了括号,这使得此类错误确实不容错过,并且对分号的放置也更加严格-但要花钱去年4天,调试嵌入式C中的一个问题,最终导致该问题的原因是某人缺少大括号放置.....我认为应该有一个编译器选项,使控制语句必须使用大括号!
Mark K Cowan 2014年

12
请提供参考资料,“ ...科学研究表明,括号...”。如果没有至少两个引用(否则这将是学习,不研究),它只是随机拍摄到空气中。
ErikE

2
@Craig,您能否提供一些线索来找到您提到的那些研究?
Grzegorz Adam Kowalski,

30

C#开发人员这样做的原因是因为它是Visual Studio自动格式化程序的默认设置。尽管可以更改此设置,但大多数人却不能,因此团队中的所有开发人员都必须选择大多数。

至于为什么这是Visual Studio中的默认值,我不知道。


15
这是Visual Studio中的默认设置,因为它是Microsoft普遍接受的编码风格,事实上,至少在Microsoft的某些团队中,该风格不仅是大括号,而且是大括号。并缩进。因此,这也是Visual Studio中的一个选项(我个人更喜欢)。
克雷格

20
@克雷格:Ewwwwwwwww
莫妮卡(Monica)

5
@PreferenceBean嗯。我个人不喜欢K&R样式,因为括号只是在行尾杂乱无章,并且文本对我来说显得很笨拙,这不仅是美学上的选择,而且对可读性/理解力有实际影响。我喜欢垂直空格。这是一个有点不同的12"显示器与昔日背课文的24线时的垂直空间是宝贵的。
克雷格

10
@克雷格:那不是缩进大括号的借口:P
莫妮卡(Monica)

2
@Craig使微软员工感到痛苦吗?
Mateen Ulhaq '16

18

-正如我在这个答案在这里假设https://softwareengineering.stackexchange.com/a/159081/29029 -我想决定与奥尔曼的支撑去可能是因为Hejlsberg创建德尔福之前,他设计了C#,帕斯卡遗产的标志。与方法名称的Pascal情况相同。

我个人相信奉行格言“在罗马就像罗马人一样”。我在C#中使用Allman,但在Java中使用K&R。我已经习惯了以任何方式切换约定对我来说都是不愉快的。

我相信某种约定的多样性实际上对于“多语言”开发人员是有益的,因为它有助于记住他们目前正在使用哪种语言编写代码,并易于区分各种习惯。可以说,这在心理上相当于肌肉的记忆。


7
实际上,“多语言开发者”行的+1。我非常喜欢大括号并缩进。但是,在诸如ASP.NET(MVC)项目的工作中,我发现我喜欢C#风格为“正确”的JavaScript和JavaScript风格为“ JavaScript”的JavaScript。这有点tongue之以鼻,但老实说,其中的一部分是JavaScript的闭包语法在该行的结尾处更具吸引力。所以我和其他人一样都是美学的奴隶……
Craig 2014年

在Anders Hejlsberg离开Borland成为Microsoft杰出软件工程师之前,很长一段时间,用于方法名称的PascalCase一直是Microsoft的标准。
Craig

2
有趣的是,我将Allman用于所有大括号语言。但是,对于Java中缩进到花括号块的预处理转换,我越来越感兴趣。一旦我将模式识别的思想包缠起来,“ java”代码看起来可能就非常干净。我认为Python可能实际上是对的:在语言中花括号的确没有太大的理由。
tgm1024 '17

使用空格控制程序流是疯狂的。如今,Python很流行,但是自从Python出现以来,这方面就有些疯狂了。
Craig

@Craig Python爱好者在这里,试图用javascript完成某些工作。查看您的其他答案以及对的编辑goto fail,使用缩进来控制程序流是人类自然想要做的事情,因此您所看到的就是执行的内容。如果缩进错了,那么普通的行不通。除了理解该程序外,还必须对这些花括号的含义进行解码,无论它们实际上是否反映了缩进,都是额外的工作。括号对于括号来说是多余的,那么为什么在括号有用的情况下程序员为什么要使用缩进呢?深度嵌套在任何语言中都是难以理解的。Jus的说。
Neil_UK

14

您与Java关联的约定是K&R样式,或“一个真正的括号样式”,最初来自C。来自古老的Jargon File的此页面缩进样式显示了这种区别有多久了。

我一直认为Allman样式及其变体反映了作者对代码的看法,将块分隔符提升到关键字级别,类似于某些语言在代码块周围使用“开始”和“结束”的方式。


我的印象是,如今的OTBS(一种真正的花括号样式)也暗示着永远不要在控制语句后留下花括号,即使对于单行代码也是如此。请参阅Apple goto失败错误。
Craig
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.