2015-05-01 19 views
16

Có cách nào trong C# (tức là trong .NET) để ném ngoại lệ tùy chỉnh nhưng không viết tất cả mã để xác định lớp ngoại lệ của bạn bắt nguồn từ Exception?Có cách nào để ném ngoại lệ tùy chỉnh mà không có lớp Ngoại lệ

Tôi đang nghĩ đến một cái gì đó tương tự như bạn có ví dụ trong Oracle PL/SQL, nơi bạn có thể dễ dàng viết

raise_application_error(-20001, 'An arbitary error message'); 

ở bất cứ nơi nào.

+0

Bạn có thể thêm thuộc tính tùy chỉnh vào một lớp ngoại lệ tùy chỉnh, vì vậy bạn không thể tạo một lớp ngoại lệ tùy chỉnh, sau đó thêm Enum cho "loại" ngoại lệ? – mellamokb

+6

Nếu 'ném ngoại lệ mới (" Một thông báo lỗi đơn phương ");' sẽ không hoạt động cho bạn, bạn nên mở rộng câu hỏi để giải thích tại sao. –

+0

Không, không có và không nên có. –

Trả lời

29
throw new Exception("A custom message for an application specific exception"); 

Không đủ tốt?

Bạn cũng có thể ném một ngoại lệ cụ thể hơn nếu nó có liên quan. Ví dụ,

throw new AuthenticationException("Message here"); 

hoặc

throw new FileNotFoundException("I couldn't find your file!"); 

có thể làm việc.

Lưu ý rằng bạn có thể là không phảithrow new ApplicationException(), mỗi MSDN.

Sự rút lại chủ yếu của việc không tùy biến Ngoại lệ là nó sẽ khó khăn hơn nếu người gọi bắt được - họ sẽ không biết đây có phải là ngoại lệ chung hay một ngoại lệ cụ thể cho mã của bạn mà không thực hiện một số kiểm tra .Message property. Bạn có thể làm điều gì đó đơn giản như thế này:

public class MyException : Exception 
{ 
    MyException(int severity, string message) : base(message) 
    { 
     // do whatever you want with severity 
    } 
} 

để tránh điều đó.

Cập nhật: Visual Studio 2015 hiện nay cung cấp một số thực hiện tự động của các lớp học mở rộng ngoại lệ - nếu bạn mở Hoạt động nhanh và Refactoring menu với con trỏ trên : Exception, chỉ nói với nó "Tạo Tất cả các nhà xây dựng".

+2

Bạn không nên sử dụng lớp 'ApplicationException', xem các chú thích ở đây: https://msdn.microsoft.com/en-us/library/system.applicationexception%28v=vs.110%29.aspx –

+0

ApplicationException là –

+0

Đây không phải là ngoại lệ "Tùy chỉnh" như OP được yêu cầu. Tuy nhiên, tôi quan tâm nhiều hơn đến việc hiểu câu này: "_Lưu ý rằng bạn có lẽ không nên ném ngoại lệ mới(), vì điều đó có thể gây ra các sự cố khác._ "- bạn có thể giải thích thêm được không? –

3

Bạn chỉ có thể ném một trong những trường hợp ngoại lệ có sẵn trong .NET:

throw new System.ArgumentException("Parameter cannot be null", "original"); 

Hoặc chung chung hơn:

throw new ApplicationException("File storage capacity exceeded."); 
6

Câu trả lời ngắn - không có.

Có lý do chính đáng để thực thi thừa kế ngoại lệ tùy chỉnh; mọi người cần có khả năng xử lý chúng. Nếu bạn có thể ném ngoại lệ tùy chỉnh của mình mà không có loại, mọi người sẽ không thể bắt loại ngoại lệ đó.

Nếu bạn không muốn viết ngoại lệ tùy chỉnh, hãy sử dụng loại ngoại lệ hiện tại.

5

Lớp Exception không phải là abstract và giống như hầu hết các ngoại lệ được xác định trong .NET, mất string message ở một trong các quá tải xây dựng - do đó bạn có thể sử dụng loại ngoại lệ hiện có, nhưng với thông điệp được tùy chỉnh.

throw new Exception("Something has gone haywire!"); 
throw new InvalidOperationException("He's Dead, Jim"); 
throw new InvalidCastException(
    string.format("Damnit Jim I'm a {0}, not a {1}!", 
     a.GetType().Name, b.GetType().Name)); 

Bởi vì đây sử dụng các loại ngoại lệ mà được biết đến, nó làm cho nó dễ dàng hơn cho các bên thrid để mở rộng thư viện của bạn là tốt, vì họ không cần phải tìm kiếm MyArbitraryException trong catch báo cáo.

+5

Tôi sẽ phải nhớ rằng 'InvalidCastException'! –

0

Cách dễ dàng để tạo ngoại lệ tùy chỉnh trong C# đang sử dụng một lớp chung. Điều này làm giảm các dòng mã đáng kể nếu bạn cần tạo nhiều ngoại lệ (nghĩa là nếu bạn cần phân biệt giữa chúng trong các bài kiểm tra đơn vị của bạn).

Đầu tiên tạo ra một lớp đơn giản gọi là CustomException<T>:

public class CustomException<T> : Exception where T : Exception 
{ 
    public CustomException() { } 
    public CustomException(string message) : base(message){ } 
    public CustomException(string message, Exception innerException) : base(message, innerException){ } 
    public CustomException(SerializationInfo info, StreamingContext context) : base(info, context){ } 
} 

Bạn có thể ghi đè lên như nhiều nhà thầu và phương pháp như bạn muốn (hoặc cần) để. Để tạo ra các loại ngoại lệ mới chỉ cần thêm lớp lót một mới:

public class MyCustomException : Exception { } 
public class SomeOtherException : Exception { } 

Nếu bạn muốn nâng cao việc bạn sử dụng tùy chỉnh ngoại lệ:

throw new CustomException<MyCustomException>("your error description"); 

này giữ đang ngoại lệ của bạn đơn giản và cho phép bạn phân biệt giữa các ngoại lệ đó:

try 
{ 
    // ... 
} 
catch(CustomException<MyCustomException> ex) 
{ 
    // handle your custom exception ... 
} 
catch(CustomException<SomeOtherException> ex) 
{ 
    // handle your other exception ... 
} 
Các vấn đề liên quan