2009-03-19 25 views
17

Câu hỏi thực hành tốt nhất đơn giản.Cảnh báo hoặc phương pháp C# Nested Try Catch?

Bạn có nên lồng câu lệnh thử hay chỉ sử dụng các phương thức. Ví dụ: nếu bạn có phương pháp mở tệp không hoạt động và đóng tệp, bạn sẽ có mở và đóng bên ngoài thử bắt, hoặc thay vì đóng trong khối cuối cùng. Ví dụ:

Bây giờ nếu phương pháp mở của bạn không thành công, phương pháp sẽ xác nhận đúng? Vì vậy, nên quấn của bạn mà trong một khối try catch hoặc nên được gọi là từ một phương pháp, mà lần lượt như là một thử bắt khối?

+0

Mẫu mã sẽ giúp minh họa câu hỏi của bạn. – Alan

+0

bất kỳ mẫu nào (mã thực tế hơn) cho câu hỏi minh họa? – Kiquenet

Trả lời

4

Tùy thuộc vào những gì bạn đang cố gắng làm, nhưng trong hầu hết các trường hợp, thử/lồng lồng nhau là dấu hiệu của hàm quá phức tạp (hoặc của một lập trình viên không biết cách ngoại lệ hoạt động!).

Trong trường hợp của tệp đang mở, tôi muốn sử dụng trình giữ IDisposable và mệnh đề sử dụng, và vì vậy sẽ không cần bất kỳ thử/nắm bắt rõ ràng nào.

7

Đây là một câu hỏi về phong cách nhưng đối với tôi, tôi cố gắng không bao giờ có nhiều cấp độ thử/nắm bắt/cuối cùng lồng trong một phương thức đơn lẻ. Tại thời điểm bạn nhấn một thử lồng nhau, bạn đã gần như chắc chắn vi phạm 1 chức năng hoạt động = 1 hiệu trưởng và nên sử dụng một phương pháp thứ hai.

+3

Tôi nghĩ rằng trong nhiều, nếu không phải hầu hết các nhà phát triển, nó sẽ không phải là vấn đề về phong cách. Nó sẽ là vấn đề không hiểu ngoại lệ trong .NET, và nghĩ rằng chúng cần phải nắm bắt mọi ngoại lệ, như trong Java. Trong hầu hết trường hợp, tốt nhất là chỉ để cho việc truyền đạt ngoại lệ. –

15

Trong ngữ cảnh của phương thức mở tệp, tôi sẽ sử dụng câu lệnh sử dụng so với lượt thử. Câu lệnh using đảm bảo rằng Dispose được gọi nếu một ngoại lệ xảy ra.

using (FileStream fs = new FileStream(file, FileMode.Open)) 
{ 
    //do stuff 
} 

làm điều tương tự như:

FileStream fs; 
try 
{ 
    fs = new FileStream(file, FileMode.Open); 
    //do Stuff 
} 
finally 
{ 
     if(fs!=null) 
      fs.Dispose(); 
} 
+3

Đóng, nhưng mã thử/cuối cùng không hoàn toàn khớp với mã sử dụng. Bạn cũng cần bọc nó trong một khối phạm vi ẩn danh. –

1

Phần lớn thời gian tôi sẽ phá vỡ các khối try/catch lồng vào các chức năng. Nhưng đôi khi tôi viết mã để bắt và ghi lại tất cả các ngoại lệ không bị bắt do ứng dụng của tôi ném. Nhưng nếu mã đăng nhập thất bại thì sao? Vì vậy, tôi có một thử/nắm bắt xung quanh đó chỉ để ngăn chặn người dùng nhìn thấy mặc định. NET unhandled ngoại lệ hộp thoại. Nhưng ngay cả mã này có thể dễ dàng được tái cấu trúc thành các hàm thay vì các khối try/catch lồng nhau.

try 
{ 
    try 
    { 
     DoEverything(); 
    } 
    catch (Exception ex) 
    { 
     // Log the exception here 
    } 
} 
catch (Exception ex) 
{ 
    // Wow, even the log is broken ... 
} 
+1

Nếu quá trình ghi nhật ký của bạn bị hỏng, bạn nên để tuyên truyền ngoại lệ để người dùng có thể phàn nàn rằng nhật ký của bạn bị hỏng! –

+0

Tôi vẫn có thể hiển thị ngoại lệ được ném bằng mã đăng nhập. Chỉ là * tôi * muốn làm điều đó thay vì để cửa sổ lỗi khung cảnh xuất hiện. –

+0

bất kỳ mẫu mẫu tốt nào bằng cách sử dụng Action ? – Kiquenet

11

Bây giờ chúng ta có lambdas và suy luận kiểu và một số nội dung khác, có một thành ngữ phổ biến ở các ngôn ngữ khác hiện có ý nghĩa rất nhiều trong C#. Ví dụ của bạn là về việc mở một tập tin, làm một cái gì đó với nó, và sau đó đóng nó lại. Vâng, bây giờ, bạn có thể tạo một phương thức trợ giúp mở tệp và cũng đảm bảo đóng/xóa/dọn sạch, nhưng gọi ra lambda mà bạn cung cấp cho phần "làm công cụ". Điều này sẽ giúp bạn có được thử/catch/cuối cùng phức tạp xử lý/dọn dẹp công cụ ngay tại một nơi, và sau đó sử dụng nó hơn và hơn.

Dưới đây là một ví dụ:

public static void ProcessFile(string filePath, Action<File> fileProcessor) 
{ 
    File openFile = null; 

    try 
    { 
    openFile = File.Open(filePath); // I'm making this up ... point is you are acquiring a resource that needs to be cleaned up after. 

    fileProcessor(openFile); 
    } 
    finally 
    { 
    openFile.Close(); // Or dispose, or whatever. 
    } 
} 

Bây giờ, những người gọi của phương pháp này không cần phải lo lắng về việc làm thế nào để mở file hoặc đóng/vứt bỏ nó. Họ có thể làm điều gì đó như thế này:

Helpers.ProcessFile("C://somefile.txt", f => 
{ 
    while(var text = f.ReadLine()) 
    { 
    Console.WriteLine(text); 
    } 
}); 
+0

Tôi có thể đặt mã "while" trong một phương thức từ một lớp khác không? – Kiquenet

+0

@alhambraeidos, nếu tôi hiểu bạn đúng, có, bạn hoàn toàn có thể. Bạn có thể tạo một phương thức gọi là "ForEachLine", mở tập tin, thực hiện một vòng lặp while để đọc nó theo từng dòng, và gọi hàm bạn truyền vào trên mỗi dòng. –

+0

Như sau: MyHelperClass4Files.ForEachLine (f); ?? – Kiquenet

3

Làm thế nào về nơi bạn có mã liên quan không nhất thiết thuộc về một chức năng riêng biệt? Điều này có đúng không?

try 
{ 
    // Part 1 Code Here 

    try 
    { 
    // Part 2 Code Here 
    } 
    catch (Exception ex) 
    { 
    // Error from Part 2 
    } 
} 
catch (Exception ex) 
{ 
    // Error from Part 1 
} 
-2
try 
{ 
    ---- 
} 
catch 
{ 
    try 
     { 
      --- 
     } 
    catch 
     { 
     --- 
     } 
} 
+0

Tại sao điều này được đưa ra một cuộc bỏ phiếu xuống? –

0
//create a switch here and set it to 0 
try 
{ 
    DoChunk1(); 
    //looks good. set the switch to 1 
} 
catch (Exception ex) 
{ 
    // Log the exception here 
} 

// kiểm tra công tắc, nếu nó vẫn không là vào thời điểm này thì bạn có thể ngăn chặn chương trình của bạn ở đây; khác đặt công tắc về 0 và thực hiện câu lệnh try try tiếp theo của bạn. hoàn toàn đồng ý với việc chia nhỏ chúng như đã đề cập ở trên

thử { DoChunk2(); // có vẻ tốt. thiết lập chuyển sang 1 } catch (Exception ex) { // Đăng trừ đây }

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