Что мы можем сделать с пользовательским исключением? - PullRequest
8 голосов
/ 21 сентября 2010

Я не знаю, что мы можем сделать с пользовательским исключением, что мы не можем сделать с встроенным.Это кажется наивным вопросом, но я действительно не знаю об этом.Что ты думаешь?

Ответы [ 7 ]

11 голосов
/ 21 сентября 2010

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

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

8 голосов
/ 21 сентября 2010

Полезно создать пользовательское исключение, если:

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

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

6 голосов
/ 21 сентября 2010

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

try
{
    EatBananas();
}
catch(OutOfBananasException oobe)
{
    GetMoreBananas();
}
catch(Exception e)
{
    TellUserAndAbort();
}

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

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

3 голосов
/ 21 сентября 2010

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

  1. операция не выполнена, но повторная попытка может быть успешной, не проводится систематическое различие;состояние системы такое же, как до операции.
  2. операция завершилась неудачно, и повторная попытка вряд ли поможет;тем не менее, состояние системы такое же, как до операции;
  3. операция завершилась неудачей таким образом, чтобы потенциально испортить что-то еще.

Может быть полезно перехватить исключения и повторно выбросить одно из трех пользовательских исключений (значений, определенных выше) в зависимости от того, где было поймано исключение.Когда исключение перебрасывается, передайте исходное исключение в качестве параметра InnerException.

Кстати, можно определить общие исключения.Я не совсем уверен в плюсах и минусах этого, и я никогда не видел, чтобы кто-нибудь еще делал это.Можно определить, например, TransientFaultException (of T), который наследуется от (пользовательского) TransientFaultException;приложение, которое перехватывает TimeoutException, может перебрасываться как TransientFaultException (от TimeOutException) и получать его как TransientFaultException (от TimeoutException) или TransientFaultException.К сожалению, нужно знать тип исключения, которому нужно научиться для создания правильного дженерика.Если бы нужно было перехватить исключение и передать его фабричному методу для TransientFaultException, новое исключение будет иметь тип TransientFaultException (из Exception), независимо от того, какой тип исключения был первоначально выдан.

3 голосов
/ 21 сентября 2010

Преимущества пользовательских исключений описаны здесь, но прежде чем создавать свои собственные, убедитесь, что BCL еще не имеет того, который соответствует вашим потребностям:

http://mikevallotton.wordpress.com/2009/07/08/net-exceptions-all-of-them/ (Их 141!)

3 голосов
/ 21 сентября 2010

В .NET есть только несколько исключений, которые обрабатываются особым образом, например ThreadAbortException , которые (обычно) не могут быть (обычно) перехвачены, обработаны и проглочены.

Кроме этого, типы исключений являются просто типами исключений. Вы можете сделать то же самое с вашими собственными исключениями, что вы можете сделать с теми, которые определены в каркасе.

2 голосов
/ 21 сентября 2010

Пользовательские исключения позволяют вам делать 2 вещи:

  1. Захват пользовательских типизированных данных в исключении
  2. Захват вхождения пользовательского исключения

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

В качестве примера, в нашем приложении у нас есть DataLayerException, который выдается, когда слой данных встречает ошибку (и включает в себя конкретное исключение СУБД в качестве внутреннего исключения).

У нас также есть DataLayerSingleResultNoneException - когда мы ожидаем один результат назад, но результата нет, и DataLayerSingleResultManyException, когда мы ожидаем один результат, но получаем много назад. Это позволяет нам улавливать различные проблемы и действовать соответствующим образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...