Abstrakter Ausnahme-Supertyp

17

Wenn das Werfen System.Exceptionso schlecht ist, warum wurde es dann überhaupt nicht Exceptiongemacht abstract?

Auf diese Weise wäre es nicht möglich anzurufen:

throw new Exception("Error occurred.");

Dies würde die Verwendung abgeleiteter Ausnahmen erzwingen, um weitere Details zu dem aufgetretenen Fehler bereitzustellen.

Wenn ich beispielsweise eine benutzerdefinierte Ausnahmehierarchie für eine Bibliothek bereitstellen möchte, deklariere ich normalerweise eine abstrakte Basisklasse für meine Ausnahmen:

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

Und dann eine abgeleitete Ausnahme mit einem genaueren Zweck:

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

Wenn Sie dann eine Bibliotheksmethode aufrufen, kann dieser generische try / catch-Block verwendet werden, um Fehler aus der Bibliothek direkt abzufangen:

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

Ist das eine gute Übung?

Wäre es gut, wenn Exceptionabstrakt gemacht würde?

EDIT: Mein Punkt hier ist, dass auch wenn eine Ausnahmeklasse markiert ist abstract, Sie sie immer noch in einem Catch-All-Block abfangen können. Es abstrakt zu machen, ist nur eine Möglichkeit, Programmierern zu verbieten, eine "Super-Wide" -Ausnahme auszulösen. Wenn Sie freiwillig eine Ausnahme auslösen, sollten Sie normalerweise wissen, um welchen Typ es sich handelt und warum dies passiert ist. So wird erzwungen, einen spezifischeren Ausnahmetyp auszulösen.

Marco-Fiset
quelle
3
+1 "Der beste Weg, eine falsche Verwendung zu verhindern, besteht darin, eine solche Verwendung unmöglich zu machen." - Scott Meyers
Steven Jeuris
3
"Wäre es gut, wenn Exception abstrakt gemacht würde?" - Absolut nicht, da der gesamte vorhandene .NET-Code, der die neue Ausnahme ("...") verwendet, beschädigt werden würde. Allerdings „sollte das .NET - Team Ausnahme abstrakt gemacht zu beginnen?“ - wahrscheinlich ja, aber es ist jetzt> 10 Jahre zu spät :)
MattDavey

Antworten:

11

Ich kenne die tatsächlichen Gründe nicht, warum das so war, und bis zu einem gewissen Grad stimme ich zu, dass es gut wäre, zu verhindern, dass unendlich weite Ausnahmen geworfen werden.

ABER ... wenn ich kleine Demo-Apps oder Proof-of-Concepts codiere, möchte ich nicht mit dem Entwerfen von 10 verschiedenen Ausnahmesubklassen beginnen oder Zeit damit verbringen, zu entscheiden, welche die "beste" Ausnahmeklasse für die Situation ist. Ich würde lieber einfach Exceptioneine Schnur werfen und übergeben, die die Details erklärt. Wenn es sich um Wegwerfcode handelt, interessieren mich diese Dinge nicht und wenn ich gezwungen wäre, mich um solche Dinge zu kümmern, würde ich entweder meine eigene GenericExceptionKlasse erstellen und diese überall hinwerfen oder zu einem anderen Werkzeug / einer anderen Sprache wechseln. Für einige Projekte stimme ich zu, dass das ordnungsgemäße Erstellen relevanter Ausnahmesubklassen wichtig ist, aber nicht für alle Projekte ist dies erforderlich.

FrustratedWithFormsDesigner
quelle
Ich stimme Ihnen vollkommen zu, aber die Frage bezog sich implizit auf nicht triviale Projekte.
Marco-Fiset
3

Möglichkeit A: Es ist logisch richtig.

Sie haben Recht, dass Microsoft, zusammen mit vielen anderen, new Exception()aus einer Vielzahl von Gründen nicht vorschlägt, direkt einen zu werfen .

Abgesehen davon können wir das akademische Ideal betrachten, dass der Zweck einer ExceptionKlassenhierarchie darin besteht, einen Verengungseffekt zu definieren, so dass nur die spezifischsten Ausnahmen erfasst werden können. (dh ArgumentNullExceptionist schmaler als ArgumentException).

Die Exception-Klasse ist keine Ausnahme (Wortspiel nicht vorgesehen). Es soll die größtmögliche Ausnahme sein, eine "Super-Ausnahme", die fast nicht erfasst werden kann, weil ihr Geltungsbereich unendlich groß ist. "Ausnahme" bedeutet nicht, abstractdass die Ausnahme nicht als eine Einheit für sich existieren kann. Es kann (obwohl zugegebenermaßen noch keine guten Fälle definiert sind - siehe Möglichkeit B) und sollte daher öffentlich konstruierbar sein.

Das Schlüsselwort 'abstract' (im rein akademischen Sinne) ist nur anwendbar, wenn die Basisklasse für sich genommen keinen Sinn ergibt - d FourLeggedAnimal. H.

In Anbetracht all dessen gäbe es keinen technischen Grund, die Klasse zu erstellenabstract , außer eine Quelle der Erschwerung für Entwickler zu sein .

Möglichkeit B: Design Lock-in / Sie wussten es nicht

Wenn MS diese Klasse abstrakt gemacht hätte, wären sie möglicherweise in Schwierigkeiten gewesen, wenn sie ihre Meinung später geändert hätten, da diese Klasse für die Grundlagen der Sprache sehr wichtig ist. Sie haben sich bereits vermasselt ApplicationException, und es ist absehbar, dass sie auch in Zukunft mit einer Änderung der Empfehlung rechnen. (siehe http://blogs.msdn.com/b/kcwalina/archive/2006/06/23/644822.aspx )

Es kann andere Gründe geben (ich denke, das hat vielleicht etwas mit Reflection zu tun, oder einen anderen technischen Grund), also mache ich diesen Beitrag zu einem CW.

Kevin McCormick
quelle
"Nur weil es" superweit "ist, ist es nicht abstrakt." ... Aber das ist das Argument des OP, nicht wahr? Sollte es nicht in dem Sinne abstrakt sein, dass immer ein Hinweis auf die Art der Ausnahme übergeben werden muss.
Steven Jeuris
Guter Punkt, ich werde meine Antwort entsprechend aktualisieren - die Art dieser Frage ist etwas verwirrend, da "abstrakt" sowohl ein Sprachschlüsselwort als auch der Name des diskutierten Konzepts ist.
Kevin McCormick
@ KevinMcCormick: Der Begriff "Zusammenfassung" wird hier als Sprachschlüsselwort verwendet. Bitte sagen Sie mir, wie ich meine Frage ändern kann, damit es für zukünftige Leser klarer wird.
Marco-Fiset
Ich denke, das ist eine gute Frage. Jede OO-Conversion in Bezug auf das abstractKeyword wird an dieser Wand angezeigt. Ich abstractbin mir nicht sicher, wie ich es umgehen soll, außer das Keyword mit den Backticks zu kennzeichnen.
Kevin McCormick
2
Wie ist es eine bahnbrechende Veränderung, eine Klasse zu "entziehen"?
Konfigurator