2010-04-22 39 views
50

Có sai không khi có câu lệnh trả về trong khối đánh bắt? Các lựa chọn thay thế là gì?
ví dụ:Quay trở lại trong khối catch?

public bool SomeFunction() 
{ 
    try 
    { 
     //somecode 
     return true; 
    } 
    catch(Exception ex) 
    { 
     MessageBox.Show(ex.message); 
     return false; 
    } 

} 
+0

Xem thêm: http://stackoverflow.com/questions/2373560/return-statements-in-catch-blocks, http: // stackoverflow.com/questions/449099/is-it-bad-practice-to-return-from-within-a-try-catch-finally-block, http://stackoverflow.com/questions/1713388/in-the- try-catch-block-là-nó-xấu-to-return-bên trong-the-catch-mà-là-tốt-practi – outis

+0

nó là tốt, tại sao không? – Andrey

Trả lời

31

Bạn có thể trở lại bình thường từ khối catch. Đó là mã chức năng bình thường.

0

Làm cho cảm giác hoàn hảo đối với tôi về một hàm trả về sự thật về thành công và sai về thất bại. Tôi hy vọng không có gì sai trong chuyện này - tôi làm điều đó tất cả các thời gian :)

18

Một thay thế sẽ được để lưu trữ các giá trị trả về trong một biến tạm thời:

public bool SomeFunction() 
{ 
    bool success = true; 
    try 
    { 
     //somecode 
    } 
    catch(Exception ex) 
    { 
     MessageBox.Show(ex.message); 
     success = false; 
    } 

    return success; 
} 

Nhưng cá nhân tôi, tôi thấy cách bạn đã viết nó (với một câu lệnh bắt tất cả) để dễ đọc hơn. Mặt khác, nếu bạn đang mong đợi một ngoại lệ cụ thể và bạn có thể có nhiều con đường để trở thành công hay không ...

try 
{ 
    DoTheImportantThing(); 
    DoTheOtherThingThatMightFailButWeDontCare(); 
} 
catch (DontCareAboutItException ex) 
{ 
    log.Info(ex); 
} 
catch (Exception ex) 
{ 
    log.Error(ex); 
    return false; 
} 

return true; 

Sau đó, theo ý kiến ​​của tôi bạn tốt nhất nên đẩy các báo cáo lợi nhuận càng gần kết thúc càng tốt.

Là một lưu ý phụ, tùy thuộc vào ứng dụng, hãy xem xét ghi lại các ngoại lệ mà bạn nắm bắt thay vì chỉ hiển thị chúng cho người dùng. Các ngoại lệ được ghi lại đáng tin cậy hơn nhiều so với những gì đã xảy ra.

7
public bool SomeFunction() 
{ 
    try 
    { 
     //somecode 
     return true; 
    } 
    catch(Exception ex) 
    { 
     MessageBox.Show(ex.message); 
    } 
    return false; 
} 

Cá nhân tôi đặt câu lệnh trả về ở cuối phương thức thay vì trong khối catch. Nhưng cả hai đều ổn. Đó là tất cả về khả năng đọc (chủ quan) và hướng dẫn trong tổ chức của bạn.

0

Mục đích chính của khối catch là cung cấp một nơi mà người ta có thể tiến hành một tình huống đặc biệt xảy ra trong khối thử. Vì vậy, bạn bắt gặp một ngoại lệ, tiến hành nó ... và trở về từ một phương pháp. Nếu phương pháp người gọi không quan tâm đến ngoại lệ, điều này là hoàn toàn bình thường.

8

Không sao, chỉ cần nhớ rằng một số mã có thể được thực hiện sau khi lệnh trả về (giá trị trả về sẽ được đổi thành tiền mặt).

try 
    { 
     return; 
    } 
    catch(Exception ex) 
    { 
     return; 
    } 
    finally 
    { 
     //some code 
    } 
9

Nếu trong khối try có đã là một câu lệnh return tôi có lẽ sẽ đặt sự trở lại khác vào cuối của hàm:

try 
{ 
    //somecode 
    return true; 
} 
catch(Exception ex) 
{ 
    MessageBox.Show(ex.message); 
} 
return false; 

Và điều này để tránh nhiều lợi nhuận nếu có nhiều trường hợp ngoại lệ cần Được xử lý.

+0

Nếu tôi làm theo mô hình đưa trở lại bên trong bắt, sau đó trình biên dịch sẽ nhắc nhở tôi với lỗi nếu trong trường hợp bằng cách nào đó trong refactoring tôi vô tình xóa báo cáo trở lại của tôi bên trong thử. Nhưng nếu tôi tiếp tục trở lại sau khi bắt thì mã sẽ biên dịch và nó có thể kết thúc trong sản phẩm. – Unnie

2

Nó không phải là sai, nhưng nếu bạn sử dụng một nguồn lực, nói chung cuối cùng khối được sử dụng để đóng nó, thay vì gọi phương pháp đóng hai lần, quá. Trong trường hợp đó, bạn có thể chọn sử dụng câu lệnh trả về sau khối cuối cùng.

+5

'cuối cùng' sẽ vẫn thực thi ngay cả khi trả về trong khối thử. – fearofawhackplanet

+1

Trong trường hợp này tuyên bố trở lại sau khi khối cuối cùng sẽ chỉ gây nhầm lẫn. Nó sẽ hoạt động, nhưng thực hành tốt là không làm phức tạp mã của bạn (quá nhiều). –

2

Có, nó hoàn toàn bình thường.

Đừng quên, bạn cũng có thể sử dụng cuối cùng là khối sẽ được thực hiện sau khi trả lại.

+2

Và do đó mã sẽ khó đọc vì mã được thực hiện sau khi trả lại. –

+2

Tôi không hiểu, bạn có cho rằng cuối cùng khó đọc không? –

+1

Đưa trở lại vào một khối catch có thể khó đọc vì bạn mong đợi sự quay trở lại bỏ qua câu lệnh cuối cùng. Điều tương tự cũng có thể nói về việc đặt một khối trả về trong khối thử. Quay trở lại thường có nghĩa là "tất cả việc thực hiện trong phương thức dừng lại và điều khiển chuyển lại cho người gọi" trong khi khối cuối cùng luôn chạy khi thoát khỏi try/catch, do đó, dự đoán sẽ được ưu tiên không dễ dàng. – Trisped

2

Nói chung, đừng làm điều đó. Vấn đề là trực quan và về mặt kỹ thuật, logic bắt giữ cần phải thoát khỏi khối catch. Ví dụ: nếu bạn có một khối cuối cùng, bạn nghĩ mã này sẽ cung cấp cho bạn điều gì?

int Test(out int t) 
    { 
     int i = 1; 
     t = 1; 
     try 
     { 
      if(DateTime.Now.Second < 58) 
       throw new Exception(); 
     } 
     catch (Exception) 
     { 
      return i; 
     } 
     finally 
     { 
      i = 2; 
      t = 2; 
     } 

     return -1; 
    } 

trả lời: nó sẽ trở về 1, nếu như chúng tôi đã thực hiện chỉ i = 1 nhưng nó sẽ có t = 2 mặc dù t = 2 xảy ra sau khi i = 2.

Như bạn sẽ nhìn thấy hình ảnh và quy tắc kỹ thuật "không có mã sau khi trả lại sẽ thực hiện" bị hỏng.

0

Bạn có thể thêm return vào khối catch. Bạn biết rõ rằng mã của bạn sẽ trả về và tiếp tục thực hiện thay vì tạm dừng tại khối catch.

try{ 
    //do something 
} 
catch{ 
    //error handling 
    return; 
} 

Thay vì có rất nhiều khối try-catch trong mã của bạn có thể gây nhầm lẫn và chỉ gây ra một mớ hỗn độn trong mã của bạn, nó tốt hơn xử lý tất cả mọi thứ trong bắt Noe thử của bạn và chỉ cần kiểm tra những gì lỗi trở lại là .

try{ 
    //do something 
} 
catch (Exception as err){ 
    if (err == "IOException"){ 
     //handle exception 
    else if (err.indexOf("TypeError"){ 
     //handle exception 
    } 
} 

Đây là hai cách kiểm tra loại ngoại lệ để bạn có thể hiển thị thông báo cho phù hợp. Bạn cũng có thể chỉ bắt các trường hợp ngoại lệ cụ thể nếu bạn muốn thay vì Exception as err bạn có thể làm catch IOException, ...

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