В C#, как я знаю который исключения поймать?

Я привык использовать общий оператор выгоды, и я обрабатываю те исключения общим способом. Эта плохая практика? Если так, как я знаю, какие определенные исключения могли быть выданы и которые я ловлю?

11
задан mcass20 28 April 2010 в 13:57
поделиться

11 ответов

  1. Да, за исключением пары очень конкретных случаев, это плохая практика. Я могу придумать один распространенный случай, когда перехват всех исключений не является плохой идеей - это когда вы регистрируете сообщение или трассировку стека непосредственно перед тем, как приложение собирается прекратить работу (или, может быть, вы регистрируете и перебрасывание).

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

19
ответ дан 3 December 2019 в 02:40
поделиться

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

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

Я рекомендую несколько ссылок:

3
ответ дан 3 December 2019 в 02:40
поделиться

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

На мой взгляд, исключения следует перехватывать только в том случае, если у вас есть веские основания для их отлова. Обычно это означает, что их перехват и обработка обычным образом не нужны. Ведение журнала исключений (очень распространенное действие в обработчике исключений) должно происходить только в нижней части стека вызовов или всякий раз, когда вы не повторно генерируете исключение (возможно, заключенное в оболочку), что должно происходить редко. Если у вас есть какое-то действие, которое вы хотите выполнять в каждом кадре в стеке вызовов, когда возникает исключение, взгляните на методы аспектно-ориентированного программирования (АОП).

0
ответ дан 3 December 2019 в 02:40
поделиться

За исключением редких ситуаций, я обычно думаю о блоках catch как о запахе кода.

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

Блоки захвата не должны быть частью логики вашего приложения.

0
ответ дан 3 December 2019 в 02:40
поделиться

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

Исключение (простите): стоит иметь что-то на самом верхнем уровне (например, Application.ThreadException или AppDOmain.UnhandledException), чтобы попытаться зарегистрировать те исключения, которые вы не обработали. Если запись не удалась, вы в любом случае обречены.

Но слепое проглатывание всех исключений (особенно на низком уровне) может привести к очень неприятным сеансам отладки / диагностики.

0
ответ дан 3 December 2019 в 02:40
поделиться

При использовании методов фреймворка вы можете проверить документацию MSDN. В каждом описании метода есть список потенциально сгенерированных исключений.

В качестве примера посмотрите параграф «Исключения» в документации File.Open () .

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

0
ответ дан 3 December 2019 в 02:40
поделиться

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

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

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

0
ответ дан 3 December 2019 в 02:40
поделиться

Более важный вопрос заключается в том, нужно ли вам выполнять определенную обработку ошибок для определенных исключений. Если вам просто нужно отловить любые возникающие ошибки, нет ничего плохого в том, чтобы просто создать общий блок try / catch:

try
{
    // Some Code
}
catch
{
}

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

try
{
    // Some Code
}
catch(ArgumentException argE)
{
}
catch(NullReferenceException nullE)
{
}
catch(Exception e)
{
    // Everything else
}

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

2
ответ дан 3 December 2019 в 02:40
поделиться

Да, это плохая практика. Эмпирическое правило: «ловите исключения, на которые вы можете отреагировать, и отпускайте другие».

try {
    File.Open(usersChosenFile, FileMode.Open);
} catch(FileNotFoundException) {
    // tell the user the file is gone, give them a chance to respond
    // this is good
} catch(UnauthorizedAccessException) {
    // this is good too
} catch(Exception) {
    // what did you just catch? Who knows. What if its OutOfMemoryException?
    // Do you really want to deal with that here? Let this one go by
}
5
ответ дан 3 December 2019 в 02:40
поделиться

IMO - не перехватывайте никаких исключений, если вы не планируете повышать их ценность и / или с ними можно справиться только этим методом.

Пожалуйста, имейте общий обработчик исключений, который обрабатывает все необработанные исключения.

HTH.

1
ответ дан 3 December 2019 в 02:40
поделиться

Как сказал Кайл, делайте ваши методы небольшими по длине, применяйте метод «try / catch» только на небольших участках. Наведите указатель мыши на методы, которые вы вызываете - тогда вы должны получить список исключений. Это не перехватит все перечисленные исключения, но исключения также можно обнаружить эмпирически, если вы напечатаете тип исключения внутри вашего catch (Исключение e) {...} . Вам нужны e.GetType (). FullName и e.StackTrace и e.Message и e.InnerException .. .или часть того, что я перечислил.

1
ответ дан 3 December 2019 в 02:40
поделиться
Другие вопросы по тегам:

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