To pytanie ma na celu zastosowanie do dowolnego języka programowania OO, który obsługuje obsługę wyjątków; Używam C # tylko w celach ilustracyjnych.
Wyjątki są zwykle zgłaszane, gdy pojawia się problem, którego kod nie może natychmiast obsłużyć, a następnie przechwytywane w catch
klauzuli w innym miejscu (zwykle zewnętrznej ramce stosu).
P: Czy istnieją uzasadnione sytuacje, w których wyjątki nie są zgłaszane i wychwytywane, ale po prostu wracają z metody, a następnie przekazywane jako obiekty błędów?
To pytanie pojawiło się dla mnie, ponieważ System.IObserver<T>.OnError
metoda .NET 4 sugeruje właśnie to: wyjątki są przekazywane jako obiekty błędów.
Spójrzmy na inny scenariusz, sprawdzanie poprawności. Powiedzmy, że postępuję zgodnie z konwencjonalną mądrością i dlatego rozróżniam typ obiektu błędu IValidationError
od osobnego typu wyjątku, ValidationException
który służy do zgłaszania nieoczekiwanych błędów:
partial interface IValidationError { }
abstract partial class ValidationException : System.Exception
{
public abstract IValidationError[] ValidationErrors { get; }
}
(Przestrzeń System.Component.DataAnnotations
nazw robi coś całkiem podobnego).
Te typy można zastosować w następujący sposób:
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(…)
}
Zastanawiam się, czy nie mógłbym uprościć powyższego:
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>
}
P: Jakie są zalety i wady tych dwóch różnych podejść?
AggregateException
zamiast tego rzucanie ? Słuszna uwaga.