Tóm tắt siêu loại


17

Nếu ném System.Exceptionđược coi là rất tệ, tại sao đầu tiên không Exceptionđược thực hiện abstract?

Theo cách đó, sẽ không thể gọi:

throw new Exception("Error occurred.");

Điều này sẽ bắt buộc sử dụng các ngoại lệ xuất phát để cung cấp thêm chi tiết về lỗi xảy ra.

Ví dụ, khi tôi muốn cung cấp một hệ thống phân cấp ngoại lệ tùy chỉnh cho thư viện, tôi thường khai báo một lớp cơ sở trừu tượng cho các ngoại lệ của mình:

public abstract class CustomExceptionBase : Exception
{
    /* some stuff here */
}

Và sau đó một số ngoại lệ xuất phát với mục đích cụ thể hơn:

public class DerivedCustomException : CustomExceptionBase
{
    /* some more specific stuff here */
}

Sau đó, khi gọi bất kỳ phương thức thư viện nào, người ta có thể có khối try / Catch chung này để trực tiếp bắt bất kỳ lỗi nào đến từ thư viện:

try
{
    /* library calls here */
}
catch (CustomExceptionBase ex)
{
    /* exception handling */
}

Đây có phải là một thực hành tốt?

Nó sẽ tốt nếu Exceptionđược làm trừu tượng?

EDIT: Quan điểm của tôi ở đây là ngay cả khi một lớp ngoại lệ được đánh dấu abstract, bạn vẫn có thể bắt nó trong một khối bắt tất cả. Làm cho nó trừu tượng chỉ là một cách để cấm các lập trình viên ném một ngoại lệ "siêu rộng". Thông thường, khi bạn tự nguyện ném một ngoại lệ, bạn nên biết nó là loại gì và tại sao nó lại xảy ra. Do đó, thi hành để ném một loại ngoại lệ cụ thể hơn.


3
+1 "Cách tốt nhất để ngăn chặn việc sử dụng không chính xác là không thể sử dụng như vậy." - Scott Meyers
Steven Jeuris

3
"Sẽ tốt hơn nếu Exception được làm trừu tượng?" - Hoàn toàn không, bởi vì tất cả các mã .NET hiện có sử dụng Ngoại lệ mới ("...") sẽ bị hỏng. Tuy nhiên, "Nhóm .NET có nên bắt đầu ngoại lệ trừu tượng không?" - có lẽ, vâng, nhưng bây giờ đã quá 10 năm rồi :)
MattDavey

Câu trả lời:


11

Tôi không biết lý do thực tế tại sao nó được thực hiện theo cách này và ở một mức độ xác nhận tôi đồng ý rằng việc ngăn chặn các ngoại lệ cực kỳ rộng rãi bị ném sẽ là một điều tốt.

NHƯNG ... khi mã hóa các ứng dụng demo nhỏ hoặc bằng chứng khái niệm, tôi không muốn bắt đầu thiết kế 10 lớp phụ ngoại lệ khác nhau hoặc dành thời gian cố gắng quyết định đâu là lớp ngoại lệ "tốt nhất" cho tình huống. Tôi chỉ muốn ném Exceptionvà vượt qua một chuỗi giải thích các chi tiết. Khi đó là mã vứt đi, tôi không quan tâm đến những thứ này và nếu tôi bị buộc phải quan tâm đến những thứ đó, tôi sẽ tạo GenericExceptionlớp của riêng mình và ném nó đi khắp nơi, hoặc chuyển sang một công cụ / ngôn ngữ khác. Đối với một số dự án, tôi đồng ý rằng việc tạo đúng các lớp con Ngoại lệ có liên quan là quan trọng, nhưng không phải tất cả các dự án đều yêu cầu điều đó.


Tôi hoàn toàn đồng ý với bạn, nhưng câu hỏi đã ngầm nghĩ về các dự án không tầm thường.
marco-fiset

3

Khả năng A: Đó là logic chính xác.

Bạn đúng là Microsoft, cùng với nhiều người khác không đề xuất ném new Exception()trực tiếp vì nhiều lý do.

Điều đó đang được nói, chúng ta có thể xem xét lý tưởng học thuật rằng mục đích của Exceptionhệ thống phân cấp lớp là xác định hiệu ứng thu hẹp để chỉ có thể bắt gặp các ngoại lệ cụ thể nhất. (tức ArgumentNullExceptionlà hẹp hơn ArgumentException).

Lớp Exception cũng không ngoại lệ (chơi chữ không có ý định). Nó được dự định là ngoại lệ rộng nhất có thể, một "siêu ngoại lệ" gần như không thể bị bắt vì phạm vi của nó là vô cùng rộng. 'Ngoại lệ' không có abstractnghĩa là Ngoại lệ có thể tự tồn tại như một thực thể. Nó có thể (mặc dù phải thừa nhận rằng chưa có trường hợp tốt nào được xác định - xem Khả năng B), và do đó nên được xây dựng công khai.

Từ khóa 'trừu tượng' (theo nghĩa thuần túy học thuật) chỉ có thể áp dụng khi lớp cơ sở không có ý nghĩa gì - nghĩa là FourLeggedAnimal.

Tất cả điều này trong tâm trí, sẽ không có lý do kỹ thuật để tạo ra lớp abstract, ngoài việc là một nguồn gây ra sự tăng nặng cho các nhà phát triển .

Khả năng B: Khóa thiết kế / Họ không biết

Nếu MS làm cho lớp này trừu tượng, họ có thể đã gặp rắc rối nếu họ thay đổi ý định, vì lớp này rất cần thiết cho các nguyên tắc cơ bản của ngôn ngữ. Họ đã đồng ý ApplicationException, vì vậy, có thể thấy trước rằng họ cũng dự đoán một sự thay đổi trong khuyến nghị. (xem http://bloss.msdn.com/b/kcwalina/archive/2006/06/23/644822.aspx )

Có thể có những lý do khác (tôi nghĩ có lẽ điều này có liên quan đến Reflection, hoặc một số lý do kỹ thuật khác), vì vậy tôi đang làm cho bài đăng này là CW.


"Chỉ vì nó" siêu rộng ", nó không trừu tượng." ... Nhưng đó không phải là lý lẽ của OP. Không nên trừu tượng theo nghĩa là một số dấu hiệu của loại ngoại lệ luôn cần phải được thông qua.
Steven Jeuris

Điểm hay, tôi sẽ cập nhật câu trả lời của mình cho phù hợp - bản chất của câu hỏi này hơi khó hiểu vì 'trừu tượng' vừa là một từ khóa ngôn ngữ cũng như tên của khái niệm đang được thảo luận.
Kevin McCormick

@KevinMcCormick: Thuật ngữ 'trừu tượng' ở đây được sử dụng làm từ khóa ngôn ngữ. Xin vui lòng cho tôi biết làm thế nào tôi có thể thay đổi câu hỏi của tôi để nó rõ ràng hơn cho độc giả trong tương lai?
marco-fiset

Tôi nghĩ đó là một câu hỏi tuyệt vời. Bất kỳ chuyển đổi OO nào liên quan đến abstracttừ khóa đều chạm vào tường này. Không chắc chắn về bất kỳ cách nào để khắc phục nó ngoài việc biểu thị abstracttừ khóa với backticks.
Kevin McCormick

2
Làm thế nào là "giải thích" một lớp thay đổi đột phá?
cấu hình
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.