Исключения: когда использовать, время, общее использование - PullRequest
1 голос
/ 31 мая 2011

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

Я недавно подключился к приложению, написанному на C #, и обнаружил механизм исключений. И у меня было несколько неудачных опытов с ними, таких как

// _sValue is a string
try
{
    return float.Parse(_sValue);
}
catch
{
    return 0;
}

Я изменил это на:

float l_fParsedValue = 0.0f;
if (float.TryParse(_sValue, out l_fParsedValue))
{
    return l_fParsedValue;
}
else
{
    return 0;
}

Результат, мой вывод в Visual Studio больше не заполняется сообщением типа

Первый шанс System.FormatException blabla

когда в фрагменте появляется строка типа '-'. Я думаю, что лучше использовать второй фрагмент.

Идя дальше, я часто видел, что исключения слишком часто используются: «Я делаю все, что хочу, в этом try-catch, если что-то пойдет не так, catch».

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

Заранее спасибо за помощь!

Ответы [ 6 ]

4 голосов
/ 31 мая 2011

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

В ваших примерах очень ясно, что TryParse лучше, так как исключение встречается часто.

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

Я рекомендую запись в блоге Эрика Липпера: Исключительные исключения

2 голосов
/ 31 мая 2011

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

Однако важно заметить, что наличие try { } catch { } само по себе не повлияет на производительность. Только когда на самом деле выдается исключение и требуется вычислить трассировку стека, вы увидите (в некоторых случаях довольно серьезное) снижение производительности.

2 голосов
/ 31 мая 2011

В случае Parse() / TryParse() лучше не ждать исключения, используйте TryParse и действуйте на неверный ввод самостоятельно.

1 голос
/ 31 мая 2011

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

- Энди Хант и Дейв Томас

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

Я могу предложить вам прочитать главы 8.3. Методы обработки ошибок и 8.4. Исключения из Код Завершен Книга.

1 голос
/ 31 мая 2011

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

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

Фрагмент, который мне запомнился при принятии решения об исключениях, взят из этой статьи :

Практически Правило № 1

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

0 голосов
/ 31 мая 2011

Ах, если бы все было так просто! Но, увы, решение, когда использовать исключения, чаще субъективно, чем нет. Тем не менее, есть рекомендации, которые вы можете использовать. Например, у Microsoft есть некоторые .

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

Обратите внимание, что здесь есть скользкая точка - должны ли ошибки валидации (пользовательского ввода) также быть выброшены как исключения? Некоторые школы мысли говорят «нет» (включая Microsoft), некоторые говорят «да». Ваш звонок. У каждого подхода есть свои преимущества и недостатки, и вам решать, как вы будете структурировать свой код.

Практическое правило для отлова исключений - вы должны отлавливать только те исключения, с которыми вы можете справиться . Теперь это тоже скользко. Является ли отображение сообщения об ошибке пользователю также «обработкой» его? Но что, если это печально известный StackOverflowException или OutOfMemoryException? Вы вряд ли можете что-либо отобразить тогда. И это могут быть не единственные исключения, которые могут оставить всю систему в непригодном для использования состоянии. Итак, еще раз - ваш звонок.

...