Вопрос по exception, c# – Должны ли мои пользовательские исключения наследовать исключение, подобное им, или просто наследовать от исключения?

8

Я создаю некоторые пользовательские исключения в моем приложении.

Если у меня есть исключение, которое выдается после проверки состояния аргумента, или у меня есть исключение, которое выдается после проверки того, что int находится в надлежащем диапазоне, должны ли мои исключения наследовать ArgumentException и IndexOutOfRangeException или они должны просто наследовать Exception?

Ваш Ответ

10   ответов
2

если у меня есть индексатор и значение индекса выходит за пределы диапазона, я бы просто выбросил существующее исключение IndexOutOfRangeException, и я бы не стал его наследовать.

Если вы говорите только о похожих, но не совсем одинаковых исключениях, взгляните на шаблон, представленный в фреймворке. Это не выглядит так, как будто это имеет смысл, наследование описывает "is-a" отношения.

@Sruly: В этом случае мой второй абзац верен, не делай этого. Унаследовать от ApplicationException и покончить с этим.
Посмотрите на мой комментарий к BFree. В этом случае исключением является ArgumentException, но оно является более конкретным. Sruly
1

нию, тогда я просто использую собственные исключения .NET, такие как IndexOutOfRangeException.

Однако, если вам нужно связать что-то с вашим исключением, которое вы не можете сделать с IndexOutOfRangeException, то я наследую это. Преимущество заключается в том, что вы можете перехватить либо новый пользовательский тип исключения, либо IndexOutOfRangeException. Конечно, если вы поймете базовый тип, у вас не будет ваших дополнительных свойств и тому подобного.

В любом случае, не легко, вы все равно можете проверить тип и привести ... (eww)
Да, и я не упомянул об этом, потому что мне пришлось бы ударить себя, если бы я это сделал.
7

что вам действительно нужно пользовательское исключение, я бы унаследовал от Исключения больше всего то, что вы ищете, а не только от Исключения.

Тем не менее, я обнаружил, что при большинстве условий использование правильной формулировки в вашем сообщении об исключении обычно будет достаточно для создания целого нового исключения.

Как, например,throw new IntOutOfProperRangeException(); значительно отличается отthrow new ArgumentOutOfRangeException("The int value was too large?");

Иногда необходимо знать (извне), когда этот int вышел за пределы допустимого диапазона. Как бы вы это проверили? Я не думаю, что хорошей идеей будет спросить, является ли выброшенное исключение исключением ArgumentOutOfRangeException, и если сообщение равно "Значение int было слишком большим?" Вместо этого я думаю, что было бы лучше сделать: try {...} catch (IntOutOfProperRangeException ex) {// обработать это}. Конечно, это зависит от вашего приложения и что вам нужно с ним делать
0

вы никогда не сможете перехватывать определенные исключения, которые являются специфическими для вашего приложения. Если вы просто используете

try 
{
}
catch (Exception ex)
{
}

Вы будете ловить каждое исключение, не имея возможности фильтровать определенные ошибки.

Еще одна причина, по которой я создаю пользовательское исключение, заключается в обработке специфических исключений приложения, которые могут возникнуть по многим причинам. Это означает, что вы хотите создать пользовательское исключение, но настроить сообщение, связанное с этим исключением. Это также дает мне другой уровень обработки ошибок, который предназначен для моего конкретного приложения.

Например, у меня есть приложение enigineering, которое определяет размеры систем ременного привода. DLL также доступна для использования другими людьми. У меня есть исключение приложения, которое выбрасывается при возникновении ошибки в выборе. Причиной ошибки может быть множество причин (неправильная скорость привода, неправильные требования к лошадиным силам и т. Д.). Поскольку существует множество причин сбоя, исключение пользовательского приложения позволяет мне указать конкретные подробности сбоя.

Это также позволяет мне документировать пользователям, что вызовы методов будут генерировать специфичные для приложения исключения, которые они должны обрабатывать.

Если унаследованный вами класс Exception, убедитесь, что в базовом классе реализованы конструкторы, которые имеют сообщение, сообщение + внутреннее исключение и сериализованное исключение.

Вот пример, который я имею.

/// <summary>
/// Drive error exception class. Thrown when a drive selection error has occured.
/// </summary>
[Serializable]
public class DriveException : ApplicationException
{
    /// <summary>
    /// Default constructor.
    /// </summary>
    public DriveException()
    {
    }
    /// <summary>
    /// Constructor used with a message.
    /// </summary>
    /// <param name="message">String message of exception.</param>
    public DriveException(string message)
        : base(message)
    {
    }
    /// <summary>
    /// Constructor used with a message and an inner exception.
    /// </summary>
    /// <param name="message">String message of exception.</param>
    /// <param name="inner">Reference to inner exception.</param>
    public DriveException(string message, Exception inner)
        : base(message, inner)
    {
    }
    /// <summary>
    /// Constructor used in serializing the data.
    /// </summary>
    /// <param name="info">Data stored to serialize/de-serialize</param>
    /// <param name="context">Defines the source/destinantion of the straeam.</param>
    public DriveException(SerializationInfo info, StreamingContext context)
        : base(info, context)
    {
    }
}
1

нет проблем с наследованием другого исключения. Это делает еще более понятной цель этого исключения. Но убедитесь, что все, что относится к ParentException, также относится и к ChildException, который вы создали. В противном случае вы можете получить«Квадрат расширяет прямоугольник» проблема...

Дело принято. Может быть, это снова ночью?
@ Моноксид: нет, квадрат расширяет (Is-A) прямоугольник. Как мои "Все квадраты являются прямоугольниками. Не все прямоугольники являются квадратами & quot;
Разве прямоугольник не расширяет квадрат? Или в этом суть? Не сталкивался с этой фразой раньше ...
только что добавили ссылку, указывающую на "Квадрат расширяет прямоугольник" проблема
4

что всегда безопаснее создать новый тип исключения. Если вам когда-нибудь понадобится изменить способ обработки, вам будет легче находить случаи, когда вы это делаете или, возможно, решаете. Найти MyException намного проще, чем найти конкретный случай ArgumentOutOfRangeException. Кажется, вы можете предоставить некоторую дополнительную информацию об исключении, и для создания исключения не так уж много работы.

Также я склонен наследовать базовый класс приложения, такой как MyBaseException, и обязательно добавлять комментарии XML для исключения / с.

+1 - Отличное замечание о создании уникальных исключений для помощи в рефакторинге.
11

какие исключения нужно перехватить, вы должны учитывать это прежде всего при принятии решения.

Подумайте об исключении IOException, которое содержит дополнительную информацию, или об исключении ArgumentException, кроме ArgumentOutOfRangeException или ArgumentNullException.

0

что все зависит от того, хотите ли вы перехватить ваше исключение ArgumentNotInPersitableState как ArgumentOutOfRange. Если будет такой блок перехвата (или если вы пишете каркас, который предположительно будет использоваться другими), тогда да, вы должны наследовать соответствующий тип исключения.

2

почему бы вам на самом деле не использовать Исключения, которые уже существуют? Похоже, что эти исключения именно то, что вам нужно, почему вы против их использования?

Для этого конкретного случая я бы унаследовал Exception напрямую.
Я проверяю вещи более специфические, чем просто общий за пределами диапазона. Например, tesitng, если аргумент находится в состоянии, которое допускает постоянство. В этом случае он проверяет аргумент, но в ралли я хочу более конкретное исключение с именем ArgumentNotInPersitableState или что-то вроде этого Sruly
Будут ли ваши абоненты ловить ваше конкретное исключение? Если нет, то вам не нужен собственный тип исключения. Просто используйте свое собственное сообщение.
0

/ или значения вне диапазона) и IllegalStateException для чего-либо не более конкретного, чем IOException, SQLException, Null ...

Похожие вопросы