#c# #try-catch
#c# #попробуйте-catch
Вопрос:
В чем разница между:
catch
{
MessageBox.Show("Error.");
}
и:
catch (Exception ex)
{
MessageBox.Show("Error.");
//we never use ex, so is it better to use catch without arguments?
}
Комментарии:
1. Во втором случае используйте
catch (Exception)
, если вы хотите перехватить этот тип или производные типы исключений, но не хотите знать подробности. В противном случае вы получите предупреждение и объявите переменную, когда она не нужна
Ответ №1:
Начиная с .NET 2, если вы не измените конфигурацию? Ничего.
До этого или с помощью какой-либо настройки конфигурации, которую я не могу точно вспомнить, существовала вероятность возникновения исключения из неуправляемого кода, который не преобразовывался в Exception
совместимый объект.
Обратите внимание, что есть еще один промежуточный вариант, где вы указываете тип, но без переменной:
catch (Exception)
{
...
}
Лично я бы очень опасался перехватывать исключение, даже не регистрируя его. Это может потребоваться, если вы вызываете тупоголовый API, но обычно этого лучше избегать.
Комментарии:
1. «существовала вероятность возникновения исключения из неуправляемого кода, который не был получен …» Таким образом, начиная с версии 2.0, он преобразуется в совместимость с исключениями? т. Е. Теперь все, что генерируется управляемым или неуправляемым, также будет перехвачено catch (исключение e){}. Кстати, я пытался поэкспериментировать с библиотекой взаимодействия Outlook, но не уверен, как получить ошибку неуправляемого кода legimate.
2. @devanalyst: Да, я полагаю , что все преобразовано в
Exception
now.3. @JonSkeet: Но в чем разница между
catch
,catch (Exception)
иcatch (Exception ex)
? Первый ничего не делает, кроме как улавливает все, второй только тип, а третий также детали? Что вы должны перехватывать, кроме исключения?4. @testing: обычно вы перехватываете определенный тип исключения. Согласно ответу, до .NET 2.0 были странные ситуации, когда
catch(Exception) { }
могли не перехватывать все, ноcatch { }
могли, IIRC. Но, к счастью, те времена давно прошли.
Ответ №2:
Я думаю, что они одинаковы. Но во втором случае возникло предупреждение компилятора, потому что вы объявляете исключение, которое вы не использовали. Мне больше нравится первый, потому что вы явно говорите, что не используете исключение. Существует также третий
catch (Exception)
{
//do something
}
если вы хотите указать тип исключения, но не заботитесь о самом исключении.
Комментарии:
1. Значит ли это, что если генерируется исключение, оно все равно попадает внутрь блока catch, даже если мы ничего не делаем с исключением?
2. @PedroGordo Да
Ответ №3:
Как правило, вы должны сначала перехватить конкретные ошибки.
Но если вы хотите поймать общее, Exception
как вы, я бы посоветовал использовать второй случай:
catch (Exception ex)
{
MessageBox.Show("Error.");
//we never use ex, so is it better to use catch without arguments?
}
это может помочь вам с удалением ошибок, поскольку переменная содержит трассировку стека, сообщение об исключении … и т.д. Который вы можете использовать для регистрации ошибки или чего-то, что поможет вам предотвратить ее.
Будьте очень осторожны, используя этот подход, хотя:
MessageBox.Show("Error.");
Отсутствие отслеживания ваших ошибок где-либо (например, в файле журнала) может привести к действительно большому беспорядку.
Комментарии:
1. Данные исключения доступны в любом случае. Если вы перейдете в исключение без переменной, появится символ, который покажет вам данные исключения.
2. @GeirGrusom — да, но вы не можете использовать эту информацию для входа в файл или что-то еще, не так ли?
3. @GeirGrusom конечно, вы можете видеть исключение при отладке, но у вас нет ссылки на него, чтобы использовать его при протоколировании или отображении соответствующего сообщения пользователю.
Ответ №4:
Во втором примере вы можете ссылаться на данные исключения, такие как трассировка стека, источник и т.д. Это также дает общее сообщение, которое иногда бывает полезным. Это говорит вам, ПОЧЕМУ вы столкнулись с исключением, что важно при отладке.
Комментарии:
1. Я думаю, вы упустили суть, первый улавливает все исключения, второй улавливает исключения .NET
2. На самом деле все, что они спросили, это в чем разница между двумя примерами catch, и в этом разница. Либо вы ссылаетесь на исключение, либо нет. И чтобы вы знали, оба примера улавливают все . Чистые исключения. Любое исключение, которое вы поймаете, будет «. Сетевое исключение», потому что это C #. Также важно отметить, что все исключения имеют класс Exception в своем дереве наследования, потому что класс exception должен наследовать его прямо или косвенно путем наследования от другого класса, который унаследовал класс Exception.
3. вы ошибаетесь, некоторые исключения не наследуются от Exception. Те, которые созданы пользовательским кодом или кодом C #, работают, но некоторые другие нет
4. Я действительно ненавижу быть втянутым в ваш троллинг, но я понял, что для того, чтобы создать исключение, вы должны наследовать от Exception. Итак, я попробовал то, что вы сказали, создал класс, а затем попытался создать его новый экземпляр. Это привело к исключению с таким сообщением «Тип, перехваченный или выброшенный, должен быть получен из System. Исключение». И что в мире вы подразумеваете под «кодом C #, но некоторые другие этого не делают». Учитывая вашу репутацию, я действительно шокирован тем, что вы не знали тривиальной обработки исключений / поведения.
5. jlafay — Опять вы ошибаетесь. Некоторый неуправляемый код (т. Е. Не C # и не .NET) генерирует исключения, которые не являются производными от Exception. С чего ты взял, что я занимаюсь троллингом?
Ответ №5:
Некоторые исключения не могут быть catch(Exception)
перехвачены.
Приведенное ниже исключение в mono на Linux, должно перехватывать без параметра.
В противном случае среда выполнения будет игнорировать catch(Exception)
statment.
System.Reflection.ReflectionTypeLoadException: The classes in the module cannot be loaded.
Если вы столкнулись с подобной проблемой, попробуйте удалить параметр catch
инструкции, зарегистрируйте переменные контекста, чтобы выяснить причину ошибки.
PS Я не знаю, как в Windows, программа, запускаемая в Windows, работает нормально.