2009-01-06 39 views
47

Tại sao chúng ta cần phải tạo ngoại lệ tùy chỉnh trong .NET?Tại sao tạo ngoại lệ tùy chỉnh?

+0

Như một trợ giúp để có thể mở lại câu hỏi này, từ [Làm thế nào để: Tạo Exceptions User-Defined] (https://msdn.microsoft.com/ en-us/library/87cdya3t% 28v = vs.110% 29.aspx) trên MSDN: * "Nếu bạn muốn người dùng có thể phân biệt theo chương trình giữa một số điều kiện lỗi, bạn có thể tạo ngoại lệ do người dùng xác định." * – DavidRR

Trả lời

48

ngoại lệ hải quan cụ thể cho phép bạn phân tách được các loại lỗi khác nhau đối với báo cáo đánh bắt của bạn.Các cấu trúc chung cho xử lý ngoại lệ là thế này:

try 
{} 
catch (Exception ex) 
{} 

này bắt tất cả ngoại lệ bất kể loại. Tuy nhiên, nếu bạn có ngoại lệ tùy chỉnh, bạn có thể có các trình xử lý riêng biệt cho từng loại:

try 
{} 
catch (CustomException1 ex1) 
{ 
    //handle CustomException1 type errors here 
} 
catch (CustomException2 ex2) 
{ 
    //handle CustomException2 type errors here 
} 
catch (Exception ex) 
{ 
    //handle all other types of exceptions here 
} 

Ergo, các ngoại lệ cụ thể cho phép bạn kiểm soát tốt hơn đối với xử lý ngoại lệ của bạn. Lợi ích này được chia sẻ không chỉ bởi ngoại lệ tùy chỉnh, mà còn tất cả các loại ngoại lệ khác trong thư viện hệ thống .NET.

3

Tôi không chắc chắn lý do "kỹ thuật" nhưng cho phép nói rằng tôi có ứng dụng/trang web sử dụng quyền. Nếu ai đó không có sự cho phép phù hợp, nó sẽ ngu ngốc khi ném một ngoại lệ DivideByZero hoặc IOException. Thay vào đó, tôi có thể tạo AccessDeniedException để giúp tôi gỡ lỗi sau này.

18

Vì vậy, bạn cũng có thể tự mình ném chúng, sau đó nắm bắt chúng và biết chính xác ý nghĩa của chúng.

Ngoài ra: nếu bạn đang xây dựng thư viện lớp/khung/api, thường hữu ích khi tạo BaseException là các ngoại lệ khác trong mã của bạn được kế thừa từ đó. Sau đó, khi mã của bạn tăng ngoại lệ, các lập trình viên đang sử dụng nó có thể nhanh chóng biết nguồn gốc của ngoại lệ.

9

Bởi vì nó có thể làm cho ý định của bạn rõ ràng và bạn cũng có thể theo dõi các tập quán sử dụng chức năng IDE. Giả sử bạn có hệ thống phụ trợ tùy chỉnh được gọi là "FooBar" và bạn thực hiện "FooBarDownException", bạn có thể theo dõi tập quán của ngoại lệ này để xác định bất kỳ logic tùy chỉnh nào mà ứng dụng của bạn chứa vì FooBar ngừng hoạt động. Bạn có thể chọn bắt loại ngoại lệ cụ thể này và bỏ qua những loại khác, tránh quá tải và logic điều kiện trong các trình xử lý ngoại lệ. Nó thực sự chỉ là một phiên bản gõ mạnh. Điều này cũng có nghĩa là bạn có thể tránh nhận xét trong mã của mình vì ngoại lệ có tên tiết lộ ý định .

+1

Tôi sẽ không nói rằng chức năng IDE là điểm bán hàng, nhưng làm cho ý định của một người rõ ràng là lý do quan trọng nhất. – casperOne

+1

IMHO gõ mạnh mẽ làm cho nó có thể thực sự * làm việc * với mã và làm cho nó tốt hơn, một enabler cho refactoring liên tục. Vì vậy, công cụ là quan trọng. – krosenvold

+0

Điều gì có nghĩa là làm cho ý định rõ ràng? Tôi có thể thấy về cách sử dụng theo dõi, vì điều này sẽ tìm tất cả các khu vực có thể bị ảnh hưởng bởi vì FooBar bị lỗi (một loại ngoại lệ chuẩn được sử dụng, chẳng hạn như ArgumentException, trong nhiều trường hợp khác nhau sẽ không cung cấp lợi ích này). – dotnetdev

3

Đó là lý do tương tự bạn sẽ tạo các mã thoát khác nhau cho một ứng dụng không phải NET: để chỉ định các lỗi ứng dụng cụ thể khác nhau. Giống như ... ConnectionBrokenException hoặc um ... UserSmellsBadException ... hoặc thứ gì đó.

Bằng cách này bạn có thể biết chính xác những gì đã xảy ra và hành động phù hợp. Ví dụ: nếu bạn cố gắng gửi một số dữ liệu và lớp truyền tải dữ liệu ném một số ConnectionBrokenException, bạn có thể bật hộp thoại kết nối lại và thử kết nối lại. Sau đó, phương pháp kết nối lại sẽ ném một ConnectionTimeoutException nếu nó hết giờ, và bạn lại có thể hành động một cách thích hợp.

1

Các ngoại lệ .NET chuẩn không bao gồm mọi thứ xấu có thể xảy ra sai trong bất kỳ ứng dụng nào cũng như chúng không có ý định. Trừ khi chương trình của bạn rất đơn giản, có khả năng bạn sẽ phải tạo ra ít nhất một vài ngoại lệ tùy chỉnh.

2

Như Joel đã viết: Vì vậy, bạn cũng có thể tự mình ném chúng, sau đó nắm bắt chúng và biết chính xác ý nghĩa của chúng.

Ngoài ra, bạn có thể thêm thông tin cụ thể về sự cố để cho trình xử lý ngoại lệ của bạn hoạt động chính xác hơn.

35

tôi đã làm một bài đăng blog dài về chủ đề này thời gian gần đây:

http://blogs.msdn.com/jaredpar/archive/2008/10/20/custom-exceptions-when-should-you-create-them.aspx

Điểm mấu chốt của nó đi xuống đến: Chỉ tạo ra một ngoại lệ tùy chỉnh nếu một trong những điều sau đây là đúng sự thật

  1. Bạn thực sự mong đợi một người nào đó để xử lý nó.
  2. Bạn muốn đăng thông tin về một lỗi cụ thể
0

Đối với một điều, Ngoại lệ được thực hiện trong Thư viện, không phải bằng ngôn ngữ - làm cách nào chúng có thể tạo ngoại lệ trong thư viện? Tôi chắc rằng bạn không ủng hộ thư viện hệ thống phải có một bộ quy tắc khác.

Đối với người khác, thực sự có thể sử dụng cây đối tượng ngoại lệ. Các ngoại lệ kế thừa của bạn có thể có các thuộc tính đặc biệt nếu bạn thích - chúng có thể được sử dụng cho những thứ phức tạp hơn chúng. Tôi không ủng hộ chúng được sử dụng như một cơ chế truyền dữ liệu chung hay bất cứ thứ gì (mặc dù chúng có thể), nhưng tôi có thể thấy một trường hợp ai đó đã triển khai giải pháp ghi nhật ký tùy chỉnh yêu cầu một thuộc tính đặc biệt trên Ngoại lệ ...

Trường hợp ngoại lệ tùy chỉnh của bạn có thể chứa cờ cho thấy điều trị đặc biệt (có thể là một câu nói bạn nên khởi động lại JVM), chúng có thể chứa thông tin về mức ghi nhật ký, một loạt các nội dung.

Dù sao, tôi không ủng hộ công cụ này, tôi chỉ nói là có thể. Đoạn đầu tiên là câu trả lời thực sự của bạn.

0

Bạn không nên nếu được xây dựng trong Ngoại lệ mô tả một cách thích hợp vấn đề/ngoại lệ. Tôi sẽ không tạo các lớp cơ sở của riêng mình để tạo một tùy chỉnh ArgumentException, ArgumentNullException hoặc InvalidOperationException.

Bạn có thể tạo ngoại lệ của riêng mình và mô tả lỗi ở cấp độ cao hơn. tuy nhiên, điều này thường không giúp ích nhiều trong việc gỡ lỗi từ một lớp người tiêu dùng.

Nếu bạn tự mình vứt và bắt ngoại lệ, ngoại lệ tùy chỉnh có thể theo thứ tự.

2

Một lý do khác, khi khách hàng trao đổi với giao diện. Vì máy khách không biết về việc triển khai giao diện và vì chúng có thể ném các ngoại lệ khác nhau, nên bạn nên tạo các ngoại lệ tùy chỉnh để thống nhất các lỗi được ném ra.

tôi đã viết về trường hợp đặc biệt này:

http://blog.mikecouturier.com/2010/01/creating-custom-exceptions-in-net-right.html

+0

Tôi không thích sử dụng 'InvalidOperationException' (hoặc, cho rằng vấn đề, hầu hết các ngoại lệ khung) cho các điều kiện mà từ đó người gọi có thể cố gắng xử lý và khôi phục. Vấn đề là ngay cả khi phương pháp được ghi lại là ném một 'InvalidOperationException' trong một số trạng thái hệ thống đã biết, cũng có thể một số phương thức được gọi nội bộ có thể ném' InvalidOperationException' khi trạng thái hệ thống bị hỏng. Nó quá xấu mà không có ngôn ngữ .net hoặc Java cho phép ngoại lệ được khai báo là 'đã chọn' tại trang web ném, với ngữ nghĩa mà người ta có thể ... – supercat

+0

... chỉ định rằng câu lệnh bắt nên chỉ bắt các ngoại lệ đã kiểm tra và các ngoại lệ được kiểm tra không bị bắt hoặc bị gắn cờ để bỏ qua chuỗi cuộc gọi sẽ trở thành ngoại lệ không được kiểm soát (vì vậy một 'catch' xung quanh một lời gọi đến phương thức' Foo() 'có thể dễ dàng phân biệt giữa' InvalidOperationException 'được ném ra vì lý do' Foo() 'mong đợi, so với cái được ném bởi một phương thức bên trong vì những lý do' Foo() 'không mong đợi. – supercat

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