Diese Frage gilt für alle OO-Programmiersprachen, die die Ausnahmebehandlung unterstützen. Ich verwende C # nur zu Illustrationszwecken.
Ausnahmen sollen normalerweise ausgelöst werden, wenn ein Problem auftritt, das der Code nicht sofort verarbeiten kann, und dann in einer catch
Klausel an einer anderen Stelle (normalerweise einem äußeren Stapelrahmen) abgefangen werden .
F: Gibt es legitime Situationen, in denen Ausnahmen nicht ausgelöst und abgefangen, sondern einfach von einer Methode zurückgegeben und dann als Fehlerobjekte weitergegeben werden?
Diese Frage stellte sich für mich, weil die .NET 4- System.IObserver<T>.OnError
Methode genau Folgendes vorschlägt: Ausnahmen, die als Fehlerobjekte weitergegeben werden.
Schauen wir uns ein anderes Szenario an, die Validierung. Angenommen, ich folge der üblichen Weisheit und unterscheide daher zwischen einem Fehlerobjekttyp IValidationError
und einem separaten Ausnahmetyp ValidationException
, mit dem unerwartete Fehler gemeldet werden:
partial interface IValidationError { }
abstract partial class ValidationException : System.Exception
{
public abstract IValidationError[] ValidationErrors { get; }
}
(Der System.Component.DataAnnotations
Namespace verhält sich ähnlich.)
Diese Typen könnten wie folgt eingesetzt werden:
partial interface IFoo { } // an immutable type
partial interface IFooBuilder // mutable counterpart to prepare instances of above type
{
bool IsValid(out IValidationError[] validationErrors); // true if no validation error occurs
IFoo Build(); // throws ValidationException if !IsValid(…)
}
Jetzt frage ich mich, ob ich das oben Gesagte nicht vereinfachen könnte:
partial class ValidationError : System.Exception { } // = IValidationError + ValidationException
partial interface IFoo { } // (unchanged)
partial interface IFooBuilder
{
bool IsValid(out ValidationError[] validationErrors);
IFoo Build(); // may throw ValidationError or sth. like AggregateException<ValidationError>
}
F: Was sind die Vor- und Nachteile dieser beiden unterschiedlichen Ansätze?
AggregateException
stattdessen? Guter Punkt.