Це питання поширюється на будь-яку мову програмування ОО, яка підтримує обробку виключень; Я використовую C # лише для ілюстративних цілей.
Виключення, як правило, призначені для збільшення, коли виникає проблема, що код не може негайно обробити, а потім потрапити в catch
пункт в іншому місці (зазвичай це зовнішній кадр стека).
Питання: Чи існують законні ситуації, коли винятки не кидаються та не потрапляють, а просто повертаються із методу, а потім передаються як об’єкти помилок?
Це питання виникло для мене, оскільки System.IObserver<T>.OnError
метод .NET 4 пропонує саме таке: винятки передаються навколо як об'єкти помилок.
Давайте розглянемо інший сценарій, валідація. Скажімо, я дотримуюся загальноприйнятої мудрості, і тому я розрізняю тип об'єкта помилки IValidationError
та окремий тип винятку, ValidationException
який використовується для повідомлення про несподівані помилки:
partial interface IValidationError { }
abstract partial class ValidationException : System.Exception
{
public abstract IValidationError[] ValidationErrors { get; }
}
( System.Component.DataAnnotations
Простір імен робить щось зовсім подібне.)
Ці види можуть бути використані наступним чином:
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(…)
}
Тепер мені цікаво, чи не можу я спростити вищезазначене до цього:
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>
}
Питання: Які переваги та недоліки цих двох різних підходів?
AggregateException
? Влучне зауваження.