【问题标题】:c# "using" statement follow by try statement can the bracket be ombitted in that case?c# "using" 语句后跟 try 语句在这种情况下可以省略括号吗?
【发布时间】:2017-12-13 17:42:52
【问题描述】:
  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
      }

上面的代码是从第 153 页 c# in a Nutshell 复制的,我不明白为什么在 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
      }
  }

【问题讨论】:

  • 我们使用块 { } 来引入多行范围,当我们想要引入单行范围时我们不使用它们 if(true) return; 在这种情况下 @987654325 @ 语句将引入它自己的多行范围。所以这不是必需的。
  • 只有当你想要包含多个语句时才需要花括号。 try-catch 是一个语句,因此不需要它们,但这是一种不好的形式。从技术上讲,您可以删除所有花括号,代码仍然会以相同的方式运行。
  • 我也觉得不妥
  • @Mahmoud 谢谢,但是如果我加上括号,没有副作用吧?谢谢
  • @juharr 你的意思是在 using 语句之后保留括号而不是删除它更好,对吧?谢谢。

标签: c# try-catch using


【解决方案1】:

如果您查看 C# Specification 中的 using 语句的语法,您会发现 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 中定义的任何语句。无论如何,要查看这是否是一个错字,您可以简单地尝试编译示例代码。

【讨论】:

    【解决方案2】:

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

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

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

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

    【讨论】:

      【解决方案3】:

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

      但是如果我加上括号,没有副作用吧?

      不,没有副作用。实际上,如果禁用了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
      

      你的意思是在using语句之后保留括号而不是删除它更好

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-17
        • 2022-01-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-27
        • 1970-01-01
        相关资源
        最近更新 更多