2017-12-13 103 views
6
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 
     } 

Đoạn mã trên được sao chép từ trang Tóm tắt, tôi không hiểu tại sao {} bị thiếu sau tuyên bố sử dụng, là lỗi đánh máy trong sách (không) hoặc không cần thiết? Như cú pháp là sử dụng cần phải theo sau bởi một khối mã bên trong {}.C# "sử dụng" câu lệnh theo sau bằng câu lệnh thử có thể đặt dấu ngoặc trong trường hợp đó không?

Tôi mong chờ mã này là:

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 
     } 
    } 
+1

Chúng tôi sử dụng khối '{}' để giới thiệu một phạm vi nhiều dòng, chúng tôi không sử dụng chúng khi chúng tôi muốn giới thiệu một phạm vi của một dòng như 'if (true) return;' Trong trường hợp này là ' Câu lệnh try' sẽ giới thiệu phạm vi đa dòng của riêng nó. Vì vậy, nó không cần thiết. – Mahmoud

+0

Dấu ngoặc nhọn chỉ cần thiết nếu bạn có nhiều câu lệnh bạn muốn đưa vào. Một thử-catch là một tuyên bố, vì vậy họ không cần thiết, nhưng đó là hình thức xấu. Và bạn về mặt kỹ thuật có thể loại bỏ tất cả các dấu ngoặc nhọn và mã sẽ vẫn hoạt động theo cùng một cách. – juharr

+0

Dường như tôi cũng thích – Paparazzi

Trả lời

10

Nếu bạn nhìn vào ngữ pháp của using tuyên bố trong C# Specification, bạn sẽ thấy rằng việc sử dụng báo cáo này được tiếp theo (hay đúng hơn, cơ thể của họ bao gồm) "embedded_statements".

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

báo cáo nhúng được định nghĩa như sau:

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 
    ; 

Vì vậy, vâng, đây không phải là một lỗi đánh máy. Sau using (...), có thể có bất kỳ câu nào được xác định trong embedded_statement. Và dù sao, để xem đây có phải là lỗi đánh máy hay không, bạn có thể chỉ đơn giản là cố gắng biên dịch mã ví dụ.

1

Nếu số {} bị bỏ qua, câu lệnh tiếp theo là câu lệnh bên dưới sử dụng. Trong trường hợp này sẽ là câu lệnh try.

Nó tương tự như câu lệnh if (hoặc bất kỳ khác):

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

{} về cơ bản nhóm một vài câu lệnh cùng biến nó thành một tuyên bố duy nhất để về cơ bản cùng một quy tắc được áp dụng.

0

Thực ra, tôi không thể thêm bất kỳ điều gì quan trọng vào Adrian's Câu trả lời tuyệt vời. Nhưng tôi sẽ trả lời các câu hỏi mới nhất của bạn về các dấu ngoặc nhọn:

nhưng nếu tôi thêm dấu ngoặc, không có tác dụng phụ phải không?

Không, không có tác dụng phụ. Trên thực tế, mã của bạn có thể kết thúc bằng một vài hướng dẫn thêm NOP trong mã IL nếu cờ Optimization bị tắt. Ví dụ Phương pháp này:

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

sẽ được đại diện trong IL như sau [Optimization cờ bị vô hiệu hóa]:

.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 

Trong khi đó, các phương pháp sau đây:

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

Will được thể hiện như sau trong mã 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 

làm bạn có nghĩa là nó là tốt hơn để giữ dấu ngoặc sau khi sử dụng tuyên bố chứ không phải loại bỏ nó

Nó phụ thuộc, trong một số trường hợp không sử dụng dấu ngoặc nhọn có thể kết thúc trong một lỗi logic. Ví dụ:

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

Nếu tôi xóa dấu ngoặc nhọn khỏi mã trước, add+=1 sẽ chỉ được thực hiện nếu điều kiện thỏa mãn. Nhưng flg=true sẽ được thực hiện luôn. Đây là một lỗi logic. Ngoài ra, bạn có thể sử dụng Curly Braces để giới thiệu phạm vi mới như tôi đã làm trong phương thức CurlyBracesMethod. r biến sẽ không được nhìn thấy bên ngoài dấu ngoặc nhọn và bất kỳ cố gắng để tham chiếu biến này sẽ kết thúc với một lỗi biên dịch. Cuối cùng, trong hầu hết các trường hợp, việc sử dụng dấu ngoặc nhọn được khuyến khích vì nó giúp làm cho mã của bạn dễ đọc hơn và dễ bảo trì hơn.

Các vấn đề liên quan