可选嵌套?这个语言功能叫做什么,它的目的是什么?

时间:2012-12-18 18:57:15

标签: c#

我遇到了一些有趣的东西,我似乎无法找到更多信息,或者是一个正确的名称。

我想我们大多数人都知道如果你有多个using块,你只需要在最后using之后加上括号:

using (FileStream fileStream = new FileStream(zipFilePath, FileMode.Open))
using (ZipInputStream zipStream = new ZipInputStream(fileStream))
{
    //stuff
}

然而,我总是发现下面的代码也是有效的,在using之后没有括号,捎带while

using (BinaryWriter br = new BinaryWriter(context.Response.OutputStream))
while (true)
{
    //stuff
}

是否有人知道允许代码块合并的此语言“功能”的名称?

7 个答案:

答案 0 :(得分:7)

是的,这是有意的。这是C♯继承自C和C ++的习语。如果您有一个用大括号括起来的单个语句,则大括号通常是可选的。无论您是否使用它们主要是风格和可读性问题。对于嵌套的using语句,通常省略外层的大括号。

语言语法

在语法术语中,using块之后是语句。通常这是阻止声明,但不一定是。

有各种各样的陈述。像a = b;这样的表达式语句。像while (boolean-expression) { ... }这样的迭代语句。这里整个while循环计为单个语句。还有块语句,它由一个或多个用大括号括起来的语句组成。

有关语句的正式规范,请参阅C#语言规范,附录C.语法,§C.2.5 Statements

  

  声明:
  标记语句
  声明语句
  嵌入语句
  嵌入语句:
  的
  空语句
  表达式语句
  选择语句
  迭代语句
  跳转语句
  尝试语句
  检查语句
  未经检查的语句
  锁定声明
  使用语句
  块:
  
{ statement-list opt }   

如果您有一个语句,通常可以省略语句周围的花括号。这些是等价的:

if (condition) statement;
if (condition) { statement; }

这些是:

using (...)
using (...)
    statement;

using (...)
using (...)
{
    statement;
}

using (...)
{
    using (...)
    {
        statement;
    }
}

有时需要

有些例外情况需要花括号。方法体必须始终具有花括号。它融入了语法。

  

  方法体:
  块
  
;
  

同样,try / catch / finally条款必须具有花括号。 checkedunchecked也是如此。你可以在语法中看到这一点。 catch子句定义为“catch block ”而不是“catch statement ”。

  

  尝试语句:
  
try 阻止抓住条款
  
try 阻止finally子句
  
try 阻止catch-clauses finally-clause
  特定追赶条款:
  
catch ( 类型标识符 opt ) 阻止<登记/>   一般追赶条款:
  
catch 阻止
  最后子句:
  
finally 阻止
  签声明:
  
checked 阻止
  未经检查的语句:
  
unchecked 阻止   

这是为什么?简短的回答是它消除了语法中的含糊之处。有关详细说明,请参阅Eric Lippert's explanation of this inconsistency.

答案 1 :(得分:3)

{ }创建一个代码块。如果你没有它们,那么下一个语句就是执行的块。因此,您正在做的事情是有道理的,因为using将适用于while

答案 2 :(得分:2)

只要您有if / else / for / while / using / foreach / {{{{}} As described by Eric Lippert 1}} / do / case / etc表达式,后面总是跟一个语句。使用大括号(switch)只是一种方法,可以在这些大括号内部创建一个语句。任何时候你自然只有一个声明,很少需要(在可能的可读性之外)使用大括号。现在,在大多数情况下,可读性足够合理,但从编译器的角度来看,它只需要任何有效的语句。

答案 3 :(得分:1)

行为是大括号运算符的行为。它创建了一个可变范围,以及其他用途。它们可以省略,代码块只是以下行。

for(int i = 0; i < 10; i++)
  foreach(blah in y)
    dosomething();

这是许多类c语言的特征。

答案 4 :(得分:1)

使用后跟一个语句,一个块是一个语句。因此,虽然通常你在使用后有一个块,你可以有一个语句,在你的例子中,但是然后,然后是一个块。

没什么不寻常的。

答案 5 :(得分:1)

在我看来,这个“概念”与允许以下内容的原理相同:

if(somethingTrue)
    when(somethingTrue)
       if(somethingTrue)
           // some code to be executed

即,单行“块”而不是括号内的几行。

答案 6 :(得分:1)

  

你只需要在最后一次使用

之后加入括号

不要求最后一次使用{ }。您的示例只是使用或不使用复合块{ }来嵌套语句的更一般功能的特殊情况。