c# "using" 语句后跟 try 语句 在这种情况下可以省略括号吗?

c# "using" statement follow by try statement can the bracket be ombitted in that case?

  using System.Net;       // (See Chapter 16)
   ...
  string s = null;
  using (WebClient wc = new WebClient()) // why there is no brackets after this using statement
      try { s = wc.DownloadString ("http://www.albahari.com/nutshell/");  }
      catch (WebException ex)
      {
        if (ex.Status == WebExceptionStatus.Timeout)

          Console.WriteLine ("Timeout");
        else
          throw;     // Can't handle other sorts of WebException, so rethrow
      }

以上代码是从 page 153 c# in a Nutshell 复制而来,我不明白为什么在 using 语句后缺少 { },这是书中的错字(不太可能)还是根本不需要?由于语法是 using 需要在 {} 内跟一个代码块。

我希望这段代码是:

  using System.Net;       // (See Chapter 16)
   ...
  string s = null;
  using (WebClient wc = new WebClient()) // why there is no brackets after this using statement
  {
      try { s = wc.DownloadString ("http://www.albahari.com/nutshell/");  }
      catch (WebException ex)
      {
        if (ex.Status == WebExceptionStatus.Timeout)

          Console.WriteLine ("Timeout");
        else
          throw;     // Can't handle other sorts of WebException, so rethrow
      }
  }

如果您查看 C# Specificationusing 语句的语法,您会发现 using 语句后跟(或者更确切地说,它们的主体由)"embedded_statements"。

using_statement
    : 'using' '(' resource_acquisition ')' embedded_statement
    ;

嵌入语句定义如下:

embedded_statement
    : block
    | empty_statement
    | expression_statement
    | selection_statement
    | iteration_statement
    | jump_statement
    | try_statement
    | checked_statement
    | unchecked_statement
    | lock_statement
    | using_statement
    | yield_statement
    | embedded_statement_unsafe
    ;

所以是的,这不是错字。在 using (...) 之后,可以有任何在 embedded_statement 中定义的语句。无论如何,要查看这是否是拼写错误,您可以简单地尝试编译示例代码。

如果省略{}则下一条语句为using下的语句。在这种情况下,这将是 try 语句。

它类似于 if 语句(或任何其他语句):

if(x == 0) return; // No {} the next statement is affected by the if

{} 基本上将几个语句组合在一起,将其变成一个语句,因此基本上适用相同的规则。

实际上,我无法为 Adrian's 好的答案添加任何重要内容。但我会回答你关于花括号的最新问题:

but if I add the brackets, there is no side effect right?

没有,没有副作用。实际上,如果 Optimization 标志被禁用,您的代码最终可能会在 IL 代码中添加一些额外的 NOP 指令。 例如这个方法:

public void CurlyBracesMethod(){
    {
        int r = 1;
        r+=2;
    }
    if(true)
        return;
}

将在 IL 中表示为以下 [Optimization 标志已禁用]:

  .locals init (int32 V_0,
           bool V_1)
  IL_0000:  nop
  IL_0001:  nop
  IL_0002:  ldc.i4.1
  IL_0003:  stloc.0
  IL_0004:  ldloc.0
  IL_0005:  ldc.i4.2
  IL_0006:  add
  IL_0007:  stloc.0
  IL_0008:  nop
  IL_0009:  ldc.i4.1
  IL_000a:  stloc.1
  IL_000b:  br.s       IL_000d
  IL_000d:  ret

而下面的方法:

public void NonCurlyBracesMethod(){
    int r = 1;
    r+=2;
    if(true)
        return;
}

IL代码中会表示为:

  IL_0000:  nop
  IL_0001:  ldc.i4.1
  IL_0002:  stloc.0
  IL_0003:  ldloc.0
  IL_0004:  ldc.i4.2
  IL_0005:  add
  IL_0006:  stloc.0
  IL_0007:  ldc.i4.1
  IL_0008:  stloc.1
  IL_0009:  br.s       IL_000b
  IL_000b:  ret

do you mean it is better to keep the brackets after using statement rather than remove it

视情况而定,在某些情况下,不使用大括号可能会导致逻辑错误。例如:

for(int i = 1;i<=n;i++){
       if(i%2==0){
         add+=1;
         flg=true;
    }
}

如果我从前面的代码中删除大括号,add+=1 将仅在满足条件(为真)时执行。但是 flg=true 将始终执行。这是一个逻辑错误。 此外,您可以使用 Curly Braces 来引入新范围,就像我在方法 CurlyBracesMethod 中所做的那样。 r 变量不会在大括号之外出现,任何引用此变量的尝试都将以编译错误告终。 最后,在大多数情况下,鼓励使用大括号,因为它有助于使您的代码更具可读性和易于维护。