如何在Delphi和C#中格式化复合语句?

时间:2008-11-14 10:31:13

标签: c# delphi coding-style code-formatting

作为Pascal和Delphi的长期开发人员,我总是将我的开头排成一行并结束:

begin
  if x = y then
  begin
     ...
     ...
  end
  else
    for i := 0 to 20 do
    begin
      ...
      ...
    end;
end;

让我疯狂的是代码格式化:

begin
  if x = y then begin
     ...
     ...
  end
  else
    for i := 0 to 20 do begin
      ...
      ...
    end;
end;

当有几个级别的复合语句时,我发现这很难读。上面的代码没问题,因为它并不复杂,但为了保持一致性,我更喜欢所有的开始和结束对齐。

当我开始使用c#时,我发现自己也会对齐花括号。 C#世界的常态是什么?

修改:

有人指出,这是一个不应该在SO上提出的问题。我不明白为什么不。我正在设置编码指南文档。我知道我会对某些事情有所抵抗,我希望能在这里得到一些答案,所以我可以随时准备迎接这种阻力。

19 个答案:

答案 0 :(得分:6)

我个人使用:

if Condition then
begin
  DoThis;
end else
begin
  DoThat;
end;

请参阅Object Pascal Style Guide

  

在复合if语句中,将每个语句放入   元素分隔新的陈述   line:示例:

// INCORRECT
if A < B then begin
  DoSomething; 
  DoSomethingElse;
end else begin
  DoThis;
  DoThat;
end;

// CORRECT
if A < B then 
begin
  DoSomething; 
  DoSomethingElse;
end 
else 
begin
  DoThis;
  DoThat;
end;
  

以下是一些被认为有效的变体:

// CORRECT
if Condition then
begin
  DoThis;
end else
begin
  DoThat;
end;

// CORRECT
if Condition then
begin
  DoThis;
end
else
  DoSomething;

// CORRECT
if Condition then
begin
  DoThis;
end else
  DoSomething;

答案 1 :(得分:4)

我以前在Delphi中使用“悬空”开头:

if (SomeCondition) then begin
  ...
end;

奇怪的是,我没有使用C,因为我发现它更具可读性:

if (SomeCondition)
{
  ...
}

过了一会儿,我停止尝试在这里和那里保存一行,以支持可读性:

if (SomeCondition) then 
begin
  ...
end;

我还使用显式的开始/结束块,我认为它提高了可读性。我不需要“聪明”。我需要能够一目了然地遵循代码的意图。更重要的是,每个人都可以阅读/维护它。

if x = y then 
begin
  ...
  ...
end
else
begin
  for i := 0 to 20 do 
  begin
    ...
    ...
  end;
end;

如果有明显的单一陈述,我通常不会打扰

if (SomeCondition) then
  ...

答案 2 :(得分:2)

我倾向于在Delphi中这样做:

if a=b then begin
  c;
end else begin
  d;
end;

if x=y then z;

因为我发现它比额外的换行符更具可读性。显然,如果我和其他人一起工作,我会使用我们同意的任何标准(或者当前代码库使用的任何标准),但是当我是唯一一个正在使用它的人时(如个人项目),那么我是这样做的。

答案 3 :(得分:2)

每个人都有不同的偏好。就我而言,在我学习Pascal之前,我学会了Modula-2。 Modula-2没有BEGIN关键字,每个块都有一个必需的END。所以代码可能看起来像这样(Modula-2碰巧使用大写关键字区分大小写):

IF x = y THEN
    ....
END;

当我开始在Pascal中编码时,它变成了:

if x = y then begin
    ....
end;

通过这种方式,代码看起来更像我以前看到的,同时仍然在可接受的Pascal代码范围内。

对我而言,这些早期的印象影响了我所喜爱的几乎所有其他语言的首选括号和缩进样式。对于C#代码,没有任何特定的“规范”,就像C或Pascal没有。

唯一真正遵循的规则是:在处理现有代码时,请使用已存在的样式。处理新代码时,请使用您喜欢的样式。

答案 4 :(得分:1)

C世界中的标准是将结束括号与起始语句对齐:

if (I am nuts) {
    Psychiatry
}

甚至将开口支撑放在自己的线上:

if (I am nuts)
{
    Psychiatry
}

在某些样式中,大括号有不同的缩进:

if (I am nuts)
  {
    Psychiatry
  }

甚至

if (I am nuts)
    {
    Psychiatry
    }

我在Perl中使用了第一种风格,这是我继续使用的方式:

if (I am nuts) {
    Psychiatry
  } else {
    I am free
}

但是在接触到Lisp之后,当我已经正确缩进时,我认为没有额外的价值可以将括号放在自己的行上:

if (I am completely nuts) {
    Psychiatry }
  else {
    I am free } 
但是,我没有希望用这些想法来改变传统的C方式。

顺便说一下,Python已经完全抛弃了括号,只依赖于缩进,但是在我的拙见中这太过分了,因为它会导致像lambda只能有一个声明这样荒谬的事情。

答案 5 :(得分:1)

我倾向于总是排队我的IF和ELSE并缩进我的BEGIN / END块。如果我有多重条件IF,我将其分成多行。如果我发现我的自我深入,那么我重新思考我正在编码或重构多种方法。所以我的代码如下所示:

if condition1 then
  begin
    // do something
  end
else // not condition1
  begin
    // do something else
  end;

或更复杂的if条件。

if condition1 or
  condition2 or
  condition3 and
  ( condition4 or
    condition5 )
then
  begin
    // do something
  end
else // not conditions
  begin
    // do something else
  end;

答案 6 :(得分:0)

我总是按照你的例子排列开始/结束。 (除了我在For语句周围有一个Begin / End之外 - 以防你以后再添加代码。)

无论如何,如果你的代码是多层次的,那么你把你的开始/结束放在哪里并不重要,因为它太复杂了。如果你发现自己结束了,比如3级深度,停止并简化。创建子程序来清理。

CodeComplete是关于这类事情的最佳参考书。如果你没有读到那本书的东西,那么我会吃掉我的帽子。

答案 7 :(得分:0)

key 单词(语法和逻辑上的键都被暴露)尽可能多地暴露时,我发现代码更具可读性。

这对我来说非常重要,有时我会诉诸(IMO)非常传统的事情。

这就是它的结果:

if (condition) then begin
  statement;
  ...
  statement; end
else begin
  ...
end;

我承认,这可以使修改代码变得不那么方便。只是我在end语句的中间找到了'悬空'if,并且与if对齐,有些令人困惑。如果它是end,则它必须是最后一个(对于语句),否则我期望else或该位置的下一个语句的开头。

then块是复合时,我通常不会让它成为复合,但else块是单个语句。对于我来说,反转条件并重新排列块并不是什么大不了的事。更重要的是,因为在使用begin ... end s包装单个语句时,我非常紧张。根据我的观点和经验,丰富的“开始 - 结束是多余的”开端往往是。虽然我喜欢它,当一个语句有一个明确的结束关键字,所以caserepeat是我的最爱。 :)

关于if s(以及while s)的另一件事是,如果遇到无人问津的情况,我倾向于放置thendo )在下一行,并在语句的起始关键词上对齐。

像这样:

if (some_long_conditional_expression) or
   (some_other_long_conditional_expression) or
   (some_even_longer_conditional_expression)
then
  Exit;

另外,这里已经提到了其他一些我不是外国人的东西,比如单行else if s(适当的时候)或for ... do with ... do try s(是的,这又可能有一些东西给我我上面提到的紧张拳击性质。)

总的来说,我可能过于依赖代码突出显示和缩进,尤其是后者。也许如果不是缩进,我宁愿总是挑出begin s。

另一点:某人的格式化风格很可能是由他们的编程风格引起的。比如,有些人讨厌非常大的例程并且倾向于尽可能地考虑因素,而其他人则更喜欢专注于代码本身而不关心那些跨越复合块的几个屏幕 - 我发现这些是非常不同的方法,这可能导致不同的格式化习惯

答案 8 :(得分:0)

在大多数情况下,只需让你的IDE缩进即可。

答案 9 :(得分:0)

哈!拿着这个! ;)

try
  if Condition1
  or (    Condition2
      and Condition3) then
    begin
      DoSomething
      DoSomeMore;
    end

  else if Condition4 then // I only do this if the nested "if" has "case"-like characteristics
    begin                 // otherwise the if would obviously be indented and on its own line
      DoSomethingElse;

      if Condition5 then
        begin
          DoThisToo;
          DoFoo;
        end;
    end

  else
    DoTheWholeShebang;

  case Whatever of
    A: DoIt;

    B, C, D:
      begin
        DoSomethingSlightly;
        MoreComplicated;
      end;

  else
    begin
      DoWhatever;
      DoLastResort; 
    end;
  end;
except
  on ESomeException do
    begin
      HandleIt;
      raise;
    end;
  on ESomeOtherException do
    DealWithIt;

  else
    DoWhateverItTakes;
end;

奇怪的是,当用花括号语言书写时,我也更喜欢尾随大括号布局:

if (condition) {
  doSomething;
} else {
  doSomethingElse;
}

答案 10 :(得分:0)

我是一个周末程序员,所以,作为唯一一个从事这些项目的人,我可以负担得起不遵循特定的编码惯例,幸运的是我。

在代码可读性方面,Castalia的structural highlighting非常有用。 CnPack有类似的功能,我不会误会。

答案 11 :(得分:0)

即使它是if中的单个陈述,我也总是使用复合begin-end  以防止将来混淆。
我还在// if之后添加了end;

if A < B then 
begin
  DoSomething; 
end; // if

其他陈述也是如此:

with qryTemp do
begin
  First;

  while not Eof do
  begin
    if (A < B)
      or (C < D)
    begin
      DoSomething;
    end else
    begin
      DoSomethingElse;
    end; // if-else        

    Next;
  end; // while
end; // with

对于C#,我遵循Code Conventions for the Java Programming Language样式复合语句。

if (condition) {
    statements;
} // if

if ((condition1 && condition2)
        || (condition3 && condition4)
        ||!(condition5 && condition6)) {
    doSomethingAboutIt();
} else {
    doSomethingElse();
} // if-else

对于Delphi和C#,连接逻辑运算符都出现在下一行的开头。

答案 12 :(得分:0)

使用一些代码格式化程序,例如来自http://jedicodeformat.sourceforge.net/

的JEDI代码格式

答案 13 :(得分:0)

这一切都很有趣。我有自己独特的对齐方式,奇怪的是,我使用多种语言,包括Pascal,C,甚至COBOL(虽然不是很长时间)。

我想我第一次在Ken Orr的课堂上看过它。我的版本也非常像有一个越位规则(类似于Python和F#),你可以使用缩进来显示嵌套。

无论如何,这是我如何做的例子:

begin  if x = y 
       then begin (* stack to avoid getting too much indentation *)
            ...     
            ...  
            end  
       else for i := 0 to 20 
             do begin      
                ...      
                ...    
                end;
       end;

是的,C / C ++ / Java / C#风味就像是

  {  if (x == y)
          {  ...   /* Space as if 'then' is there */  
             ...  
             }
     else for (int i = 0; i<21; i++)
              {  ... /* space as if 'do' is there */
                 ...  
                 }
     }

我经常使用它。你可以像开始和结束一样堆叠{和},但是我发现能够看到边缘并确认匹配的括号和缩进组的结尾更令人愉快。我不同的是保持缩进过度,避免过多的“{”和“}”独自站在空白的海洋中。

我不传福音。没有人抱怨能够阅读它。将“{”放在一行的末尾似乎是来自Ratfor预处理器的延续,这就像Python在某些地方需要(更令人愉快的)“:”的方式。当我可以更有用地使用左边缘上的对齐时,我不想在代码中扫描不规则的右边缘。

正如我们在这里所说,YMMV

答案 14 :(得分:0)

前段时间我用过

if <cond> then
  begin
  ShowMessage('balablala');
  exit;
  end;

但现在我按照

的标准
if <cond> then
begin
  ShowMessage('balablala');
  exit;
end;

Object Pascal Style Guide

一样

答案 15 :(得分:0)

有人说他们会写下以下内容:

if x=y then z;

现在我真的不喜欢,这与美学无关。让我们假设x,y和z是函数,如果我单步执行代码,上面意味着我不能跨越x和y,并进入z。

1   if x=y then
2     Z;

我现在可以进入第2行而不会进入第1行。

答案 16 :(得分:0)

就个人而言,我更喜欢在一行压缩加入语句。例如。 end else在一行上。使下一个语句块与当前语句块相关更清楚。

答案 17 :(得分:0)

我永远不会那样写代码(你的第二个例子)。它将是(首选)

begin
  if x = y then begin
     ...
  end
  else begin
    for i := 0 to 20 do begin
      ...
   end;
  end;
end;

begin
  if x = y then begin
     ...
  end
  else for i := 0 to 20 do begin
     ...
  end;

端;

有时我会使用这样的折叠(如第二种情况)来组合if和try..finally。

x := GetMeTheObject;
if assigned(x) then try
  ...
finally FreeAndNil(x); end;

答案 18 :(得分:0)

之前有人问过。例如c-coding-standard-best-practices