【问题标题】:When are curley braces required around single statements?何时需要在单个语句周围使用花括号?
【发布时间】:2011-08-05 00:18:01
【问题描述】:

在我的回答中:C# Lock syntax - 2 questionsLukeH 指出try...catch...(finally) 语句需要大括号。

我找到了原因的答案,在这里 (Why do try..catch blocks require braces?) 找到了非常有趣的答案。

我想知道更多需要大括号而不是良好做法等的示例,最好使用代码 sn-p 并解释原因。

【问题讨论】:

  • 如果您使用“剃须刀”,它们总是是必需的。我实际上有点希望我有一个启用此模式的 csc 编译器开关。
  • 同意,我发现 if 等下的单行语句在添加 {...} 时更具可读性。排序和卷曲。 :D

标签: c# curly-braces curly-brackets


【解决方案1】:

围绕方法体。

// not allowed:
int Inc(int x) 
     return x+1; 

为什么并不那么容易,似乎老式 C 比 C++/C# 更需要它。

更多关于为什么部分,在(非常)旧的 C 中你会写

int Sum()
int a, b; // parameters, very informal
{
   int s; // local var
   ...
}

所以这个古老的语法需要大括号。在所有基于 C 的语言中,没有人认为将它们设为可选,假设在某些情况下这是可能的。

【讨论】:

  • 你能想出一个理由吗?我正在尝试考虑何时会有歧义(例如答案 re. the try...catch 示例)但不能。
  • 在 C# 语法中可能使它们成为可选的,但为什么设计者还要表呢?
【解决方案2】:

语言的某些部分需要大括号。例如,当您启动一个方法时,您必须打开和关闭大括号以将其标识为代码块。在函数内部,某些语言特性(如循环、条件语句等)也接受大括号,尽管在某些情况下它们不是必需的。例如:

if (someValue == true)
    doSomething();

在这种情况下不需要大括号,但是你可以用大括号包围这个语句,因为你只有一个语句将在 if 检查之后执行,但是如果你想在 if 中执行多个语句,你需要使用大括号.例如,

if (someValue == true)
{
    doSomething();
    doSomeMoreWork();
}

不允许尝试这样的事情:

if (someValue == true)
    doSomething();
    doSomeMore();
else
    doWork2();
    int i = 1 + 2;

在这种情况下编译器会报错。

问题最好在以下循环中看到:

while(i < 10)
    doSomeWork();
    i++;

在这里你会期望 i 增加,但这永远不会发生。基本上这个循环和这个循环是一样的:

while(i < 10)
{
    doSomeWork();
}

i++;

块内的语句将无限执行,我永远不会增加。在这种情况下,编写此语句的正确方法是:

while(i < 10)
{
    doSomeWork();
    i++;
}

现在您有了一个正常工作的语句。无论正在执行的语句数量如何,我都喜欢一直使用大括号。这样做的原因是迟早我可能需要在 if 语句或 for 或 foreach 循环中添加更多工作。这只是一个好习惯。

【讨论】:

  • @Downvoter 帖子被否决的任何具体原因?
  • Huske,一个很长的答案,但完全错过了这个问题。
  • 我不太同意 Henk 的观点,但很公平。我认为回答何时以及为什么需要它是相当困难的,所以我尝试描绘一些案例并给出何时以及如何使用大括号的想法。
  • 我认为乔治可能会选择一个更具体的标题。
【解决方案3】:

您必须在checkedunchecked 中使用either 大括号 括号,具体取决于您将它们视为运算符还是语句:

// legal operator
int y = checked(x * 2);

// legal statement
unchecked
{
    if ((a * b) > c)
    {
        DoSomething();
    }
}

// illegal operator
int y = checked x * 2;

// illegal statement
unchecked
    if ((a * b) > c)
        DoSomething();

【讨论】:

  • 强调一下,运算符/表达式版本checked()的存在很好地回答了这里的为什么部分。
  • @Henk:确实,虽然我不明白为什么编译器不能执行某种上下文分析来确定正在使用的版本。 (但仅仅因为我看不到潜在的陷阱并不意味着没有任何陷阱。我敢肯定会有一些棘手的极端情况。只执行大括号/括号规则会更容易且不那么模棱两可。)
  • 也许最好把它分成 2 个答案。开关情况是labels,如goto label12; 并遵循该语法模式。不过有一些关于 switch 和 scope 的特殊规则。
  • @Henk:是的。我想我可能会完全删除switch 的东西;我只是出于好奇才提到它。尽管 switch 部分不是只是简单标记的语句。例如,编译器不允许 switch 部分从一种情况切换到另一种情况。
  • 我仍然认为switch 符合问题的“需要大括号”精神。例如,while (expression) {} 是合法的,while (expression); 也是合法的,而 switch (expression) {} 是合法的,但 switch (expression); 是不合法的。
【解决方案4】:

类/结构/接口声明

类 X { int _myval }

【讨论】:

  • 是的,但语法的部分非常不同。一个类不包含语句,而是声明。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-31
  • 1970-01-01
  • 1970-01-01
  • 2012-02-03
相关资源
最近更新 更多