Тут все сильно зависит. Если отталкиваться от теории, то исключение это нарушение состояния типа(класса): предусловие, пост условие и инвариант, другими словами класс не может выполнить декларируемый контрактом функционал.
Если у вас нет каких-то узкоспециализированных "но", то надо бросать исключение, потому как код обработки в текущем вызове может не знать, а скорее всего и не должен знать что ему делать если произошел выход за пределы. А вот тот кто проверяет, может знать что ему делать, если произошел выход за пределы, и в этом случае целесообразно расширить интерфейс типа и добавить возможность проверки. Обычно такой подход используется в бизнес логике.
Решать надо не со стороны производительности, а со стороны того, что лучше подходит — исключение или дополнительная проверка (когда, где и как использовать исключения — это отдельная большая тема). Если у вас в цикле не выбрасываются тысячи исключений в секунду, то на производительность надо смотреть в самую последнюю очередь (или скорее вообще не смотреть, исключения не настолько тормозные вещи, чтобы их бояться и даже тратить время на то, чтобы задумываться об их производительности). А если выбрасываются тысячи исключений, то надо критически посмотреть на дизайн такого решения.
Re[2]: На сколько затратно выбрасывание исключения
Здравствуйте, MozgC, Вы писали:
MC>Решать надо не со стороны производительности, а со стороны того, что лучше подходит — исключение или дополнительная проверка
Вы там сговорились, что ли?
Есть официальные гадлайны, что и когда использовать. В частности
Do not use exceptions for normal flow of control. Except for system failures, there should generally be a way to write code that avoids exceptions being thrown.
Если есть сомнения — проверяем бенчмарком. Он наглядно показывает, что рекомендации не на пустом месте написаны
А всё просто: исключения в дотнете заточены под исключительные ситуации (сорри за фиговый каламбур). Если производительность утыкается в стоимость обработки исключений, то проблема уже на 100% не в них самих, а в непродуманной архитектуре / незнании матчасти / неправильно написанном API и тд и тп. Исключений из этого правила на практике не видел.
Ну и разумеется в крайности не надо впадать. Исключения отлично работают для отмены/отката бизнес-операций (кучу понятных оговорок про необходимость отката состояния, побочные эффекты и тд и тп пропустим). А вот писать try-catch вокруг метода проверки заказа — это уже перебор
Ну и собственно вопрос: как можно прочитать рекомендацию "не делайте так" и прийти к прямо противоположным выводам типа:
В общем после прочтения указанных ссылок я сделал вывод, что если речь идет о производительности, то использования исключений нужно избегать. А в остальных случаях все зависит от ситуации.
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, MozgC, Вы писали:
MC>>Решать надо не со стороны производительности, а со стороны того, что лучше подходит — исключение или дополнительная проверка
S>Есть официальные гадлайны, что и когда использовать. В частности
S>Do not use exceptions for normal flow of control. Except for system failures, there should generally be a way to write code that avoids exceptions being thrown.
А я где-то рекомендовал использовать исключения "for normal flow of control"?
S>Если есть сомнения — проверяем бенчмарком.
Сомнения могут появляться когда есть шанс, что исключение будет выкидываться с очень большой частотой. В противном случае, повторюсь, при принятии решения в первую очередь надо основываться на том, как будет лучше/правильнее в плане дизайна.
S>Он наглядно показывает, что рекомендации не на пустом месте написаны
ТС собирается это исключение выбрасывать тысячи раз в секунду? Если нет, то зачем считать микросекунды, по крайней мере пока не замечена проблема с производительностью?
S>Ну и собственно вопрос: как можно прочитать рекомендацию "не делайте так" и прийти к прямо противоположным выводам типа: S>
S>В общем после прочтения указанных ссылок я сделал вывод, что если речь идет о производительности, то использования исключений нужно избегать. А в остальных случаях все зависит от ситуации.
S>Решать надо не со стороны производительности, а со стороны того, что лучше подходит — исключение или дополнительная проверка
S>
Ты под рекомендацией "не делайте так" имеешь в виду не использовать исключения "for normal flow of control"? Если да, то я не вижу противоречия между этой рекомендацией и тем что я написал, т.к., повторюсь, я не рекомендовал использовать исключения для "normal flow of control".
S>Ладно один человек ошибается, но четыре? (отплюсовавшие vrr и Sharov, я вас тоже посчитал )
Ммм.. я пока не вижу, что я ошибаюсь
Re[4]: На сколько затратно выбрасывание исключения
MC>А я где-то рекомендовал использовать исключения "for normal flow of control"?
Ну, по крайней мере я так понял вот эту часть — "... со стороны того, что лучше подходит — исключение или дополнительная проверка".
Официальные рекомендации тут крайне однозначны: если в коде возникла ситуация, которую код не знает, как обрабатывать, или если контракт вызова нарушен — бросай исключение.
На случай, если вызывающий код знает, как эту ситуацию обрабатывать есть стандартные tester-doer или TryParse.
Собственно, это всё, что надо знать для выбора "бросать-не-бросать". Разумеется, есть исключения, но они строго индивидуальны и всегда начинаются с конкретного сценария использования. Из практики я могу вспомнить только один рабочий хак, ради которого имеет смысл отступать от правила выше: откат бизнес-операций.
Любой бизнес-код по определению должен уметь откатывать изменения до согласованного состояния, если в ходе выполнения произошла ошибка. Если это правило не соблюдается, то у клиента рано или поздно поизойдёт страшное(тм) и это страшное будет исправить гораздо дороже, чем подумать о корректной обработке исключений с самого начала.
Ну а дальше следует очевидное: раз мы потратили кучу усилий на соблюдение атомарности биз-операций, то грех не использовать готовый код для обработки бизнес-исключений. Например, в ходе оформления заказа внезапно выясняется, что выбранные пользователем товары нельзя экспортировать в страну назнчения. Конечно, можно нагородить фреймворк для валидации бизнес-правил или "холостой прогон" бизнес операции с последующей проверкой корректности и коммитом.
Иногда это даже будет оправданно, но в большинстве случаев достаточно бросить BusinessException(Resources.XyzMessage) и не заморвчиваться.
S>>Если есть сомнения — проверяем бенчмарком. MC>Сомнения могут появляться когда есть шанс, что исключение будет выкидываться с очень большой частотой.
Бенчмарк нужен в любом варианте, потому что у всех понятие "большая частота" разное. Выше по ветке Влад закладывался на миллионы, у тебя — тысячи. На практике даже сотня исключений в секунду на нагруженном сервисе может очень здорово нагадить.
Но! это не значит, что проверки с исключениями надо убирать из кода, "так как производительность". Иначе рано или поздно получим мой сегодняшний кейс:
cache.TryGet(objKey, out obj);
obj.DoSomething();
Автор API хотел как лучше и не предоставил метода, бросающего исключение. В принципе, когда-то это было оправданно, т.к. метод использовался в ограниченном количестве мест. Но к моменту, когда ошибка всплыла, код успел разползтись по нескольким классам, местами породив комбайны для протаскивания сигнала об отмене обратно по стеку. И чтобы было совсем весело, другая добрая душа "починила" код, возвращая new Obj() в случае промаха мимо кэша
В общем, смотрим оф. рекомендации, любое отступление начинаем с реального сценария использования, получившееся API документируем тестами/ассертами (которые суть те же исключения). Иначе никак
MC>ТС собирается это исключение выбрасывать тысячи раз в секунду?
Именно, выше по ветке было:
Cynic:
Например возьмём такой пример: Есть у меня есть некий буфер, который может периодически переполняться и переполнение нужно как-то обрабатывать. Я могу решить эту проблему двумя путями:
Выбросить исключение в коде буфера и обработать во внешнем коде
Всякий раз при добавлении элемента проверять есть ли в буфере место
При этом операции записи в буфер происходят довольно часто. Правильно ли я понимаю, что в данном случае лучше избегать исключений?
Я кажется понял, в чём проблема: ты не просматривал весь топик, а я отвечал именно в контексте ветки, где уже было несколько ответов в духе "раз исключения тормозят, то можно их не бросать"
Как всегда короче
Re[2]: На сколько затратно выбрасывание исключения