Jeśli rzucanie System.Exception
jest uważane za tak złe, dlaczego nie zostało Exception
wykonaneabstract
?
W ten sposób nie będzie możliwe wywołanie:
throw new Exception("Error occurred.");
Wymusiłoby to użycie wyjątków pochodnych, aby podać więcej szczegółów na temat błędu, który wystąpił.
Na przykład, gdy chcę podać niestandardową hierarchię wyjątków dla biblioteki, zwykle deklaruję abstrakcyjną klasę bazową dla moich wyjątków:
public abstract class CustomExceptionBase : Exception
{
/* some stuff here */
}
A potem kilka wyjątków pochodnych o bardziej szczegółowym celu:
public class DerivedCustomException : CustomExceptionBase
{
/* some more specific stuff here */
}
Następnie podczas wywoływania dowolnej metody bibliotecznej można mieć ten ogólny blok try / catch, aby bezpośrednio wychwycić dowolny błąd pochodzący z biblioteki:
try
{
/* library calls here */
}
catch (CustomExceptionBase ex)
{
/* exception handling */
}
Czy to dobra praktyka?
Czy byłoby dobrze, gdyby Exception
został streszczony?
EDYCJA: Chodzi mi o to, że nawet jeśli klasa wyjątku jest zaznaczona abstract
, nadal możesz złapać ją w bloku catch-all. Uczynienie go abstrakcyjnym to tylko sposób, aby zabronić programistom zgłaszania wyjątku „super-szeroki”. Zwykle, kiedy dobrowolnie zgłaszasz wyjątek, powinieneś wiedzieć, jaki to typ i dlaczego tak się stało. Wymuszając w ten sposób wyrzucenie bardziej konkretnego typu wyjątku.
źródło
Odpowiedzi:
Nie znam rzeczywistych powodów, dla których tak się stało, i do pewnego stopnia zgadzam się, że zapobieganie rzucaniu nieskończenie szerokich wyjątków byłoby dobrą rzeczą.
ALE ... podczas kodowania małych aplikacji demonstracyjnych lub sprawdzania koncepcji, nie chcę zaczynać projektować 10 różnych podklas wyjątków ani spędzać czasu na podejmowaniu decyzji, która z nich jest „najlepszą” klasą wyjątków w danej sytuacji. Wolę po prostu rzucić
Exception
i podać ciąg, który wyjaśnia szczegóły. Kiedy nadszedł jednorazowe kod, nie dbam o tych rzeczach i gdybym został zmuszony do dbania o takich rzeczach, to bym albo stworzyć własnąGenericException
klasę i rzucać , że wszędzie, albo przenieść się do innego narzędzia / języka. W przypadku niektórych projektów zgadzam się, że prawidłowe tworzenie odpowiednich podklas wyjątków jest ważne, ale nie wszystkie projekty tego wymagają.źródło
Możliwość A: To logicznie poprawne.
Masz rację, że Microsoft wraz z wieloma innymi nie sugerują rzucania
new Exception()
bezpośrednio z wielu powodów.Biorąc to pod uwagę, możemy uznać akademicki ideał, że celem
Exception
hierarchii klas jest zdefiniowanie efektu zwężenia, tak aby można było wychwycić tylko najbardziej specyficzne wyjątki. (tzn.ArgumentNullException
jest węższy niżArgumentException
).Klasa Exception nie jest wyjątkiem (kalambur nie jest przeznaczony). Ma to być najszerszy możliwy wyjątek, „super wyjątek”, którego prawie nie można uchwycić, ponieważ jego zakres jest nieskończenie szeroki. „Wyjątek” nie jest
abstract
że wyjątek nie może istnieć jako całość sama w sobie. Nie może (choć wprawdzie nie określono jeszcze dobrych przypadków - patrz możliwość B), a zatem powinna być publicznie możliwa do zbudowania.Słowo „abstrakcyjne” (w sensie czysto akademickim) ma zastosowanie tylko wtedy, gdy klasa podstawowa sama w sobie nie ma sensu - tj
FourLeggedAnimal
.Wszystko to na uwadze, nie byłoby techniczny powód, aby zrobić klasę
abstract
, inna niż być źródłem pogorszenia deweloperom .Możliwość B: Design Lock-in / Nie wiedzieli
Jeśli stwardnienie rozsiane uczyniło tę klasę abstrakcyjną, mogliby mieć kłopoty, gdyby zmienili zdanie na później, ponieważ klasa ta jest bardzo istotna dla podstaw języka. Oni już wygłupili się
ApplicationException
, więc można przewidzieć, że spodziewali się również zmiany rekomendacji na późniejszym etapie. (patrz http://blogs.msdn.com/b/kcwalina/archive/2006/06/23/644822.aspx )Mogą istnieć inne powody (myślę, że może to ma związek z Reflection lub z innych przyczyn technicznych), dlatego wpisuję ten post w CW.
źródło
abstract
słowa kluczowego trafiają w tę ścianę. Nie jestem pewien, jak można to obejść poza oznaczeniemabstract
słowa kluczowego za pomocą strzałek wstecznych.