2009-02-20 30 views
5

Nếu tôi có mã như thế này:ngoại lệ bắt thực hành tốt nhất (. C#/net)

void a() 
{ 
    try 
    { 
     b(); 
    } 
    catch (MyException) 
    { 
     // Handle any problems that occurred in b(c(d())) 
    } 
} 

void b() 
{ 
    c(); 
    // Do something else 
} 

void c() 
{ 
    d(); 
    // Do something else 
} 

void d() 
{ 
    // Do something, throw a MyException if it fails 
} 

Giả sử không dọn dẹp là cần thiết bất cứ lúc nào, nó là tốt nhất để đặt một try {} catch {throw;} xung quanh cuộc gọi đến d() trong c() và cuộc gọi đến c() trong b() hoặc là nó được coi là OK để cho ngoại lệ từ d() bong bóng lên đến một() "tự nhiên" mà không có bất kỳ can thiệp cố gắng/bắt khối?

Tôi cho rằng khối try/catch bổ sung hoạt động như một loại "tài liệu" nhưng chúng dường như không cần thiết vì vậy tôi chỉ tự hỏi những người khác sẽ xem xét cách tốt nhất.

Xin lỗi nếu điều này hơi quá cơ bản, tôi đang cố gắng giải quyết các ngoại lệ nhưng tôi dường như không có cảm giác tốt cho họ.

+0

Liên quan đến http://stackoverflow.com/questions/22623/-net-throwing-exceptions-best-practices – gimpf

Trả lời

13

Để nó truyền cho đến khi bạn có thể xử lý. Nếu bạn không thể xử lý nó, không có điểm nào bắt được nó. Vì vậy, câu hỏi là, bạn có thể xử lý hiệu quả ngoại lệ bên trong phương thức c() không?

0

Tôi muốn nói, điều đó phụ thuộc vào những gì bạn muốn làm với thông tin.

Tôi luôn cố gắng nắm bắt các vấn đề càng gần nguồn càng tốt - tại sao lại chạy ngược lại với vấn đề, thay vì cố giải quyết vấn đề xảy ra ở đâu? Để dễ đọc và hiểu được mã, tôi cũng tin vào việc thử/nắm bắt càng gần nguồn gốc của vấn đề càng tốt.

Nếu bạn đang viết chương trình cho chính mình và không ai khác sẽ chạm vào nó, hãy làm bất cứ điều gì phù hợp nhất với bạn và mã.

3

Về cơ bản, không. Đây không phải là cách được đề xuất để xử lý các tình huống này.

Bạn nên bắt ngoại lệ khi và chỉ khi bạn có thể xử lý chúng và làm điều gì đó phù hợp với chúng hoặc cung cấp thêm thông tin cho người gọi cao hơn trong ngăn xếp cuộc gọi (bằng cách đóng gói nó trong một ngoại lệ chung chung hơn). Nếu bạn không thể làm điều đó, bạn nên để cho các trường hợp ngoại lệ bong bóng lên trong ngăn xếp cuộc gọi cho đến khi ai đó có thể xử lý nó một cách thích hợp.

3

Lợi thế lớn nhất của ngoại lệ là bạn có thể giải quyết các vấn đề mà bạn có thể làm điều gì đó về chúng, thay vì trực tiếp trong hàm, ví dụ: một tập tin bị thiếu được phát hiện, hoặc trong người gọi của hàm, hoặc người gọi của nó, & c.

Tuy nhiên, ngoại lệ cũng để được xử lý ở đâu đó dọc theo chuỗi. Nơi những điểm này xảy ra phụ thuộc vào khung bạn đang sử dụng và quản lý ngoại lệ của nó bao gồm. Câu hỏi quan trọng là: điểm nhập cảnh của bạn là nơi cho phép ngoại lệ trốn thoát sẽ có tác dụng xấu? Ví dụ điển hình bao gồm

  1. Mã xử lý sự kiện trong ứng dụng UI tương tác (ít nhất trong WinForms và ASP.NET có thể bị bắt bằng cách cung cấp exception event handlers).
  2. Điểm tích hợp nơi bạn trả lời thư bên ngoài (ví dụ: nhận thư từ hàng đợi, xử lý tệp, nghe trên đường ống có tên, triển khai dịch vụ WCF).
  3. Sự kiện hẹn giờ nơi bạn thực hiện xử lý nền.
  4. Phương thức bắt đầu chủ đề.

Đôi khi, bạn cũng muốn gặp lỗi kỹ thuật chung ở mức độ thấp và thử lại nó dưới dạng ngoại lệ cụ thể cho từng miền. Điều này thường được thực hiện trong các thư viện được thiết kế tốt để bảo vệ người dùng khỏi các chi tiết triển khai nội bộ của nó. Trong một ứng dụng doanh nghiệp, bạn có thể muốn nắm bắt một số SqlExceptions và tái cấu trúc chúng dưới dạng các ngoại lệ dành riêng cho ứng dụng (ví dụ: YourApp.UnknownCustomer), để đối phó với chúng ở các mức logic cao hơn.

Lời khuyên của tôi sẽ là: giải quyết các vấn đề ở mức cao nhất có thể, nhưng đảm bảo rằng người bắt ngoại lệ có những ngoại lệ hợp lý để làm việc. Và, bằng cách này, trừ khi bạn ghét người dùng của bạn, không hiển thị ngoại lệ và theo dõi ngăn xếp của họ cho họ! ;-)

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