Давайте проанализируем одну из самых больших возможных затрат блока try / catch при использовании там, где его не нужно использовать:
int x;
try {
x = int.Parse("1234");
}
catch {
return;
}
// some more code here...
А вот тот, у которого нет try / catch:
int x;
if (int.TryParse("1234", out x) == false) {
return;
}
// some more code here
Не считая незначительного пробела, можно заметить, что эти два равносторонних фрагмента кода имеют практически одинаковую длину в байтах. Последний содержит на 4 байта меньше отступа. Это плохо?
Чтобы добавить оскорбление к травме, студент решает зациклить, в то время как ввод может быть проанализирован как int. Решение без try / catch может выглядеть примерно так:
while (int.TryParse(...))
{
...
}
Но как это выглядит при использовании try / catch?
try {
for (;;)
{
x = int.Parse(...);
...
}
}
catch
{
...
}
Блоки try / catch - это волшебные способы потратить впустую отступы, и мы до сих пор даже не знаем, почему это не удалось! Представьте себе, что чувствует человек, выполняющий отладку, когда код продолжает выполняться после серьезного логического недостатка, а не останавливается с приятной очевидной ошибкой исключения. Блоки try / catch - это проверка / очистка данных ленивым человеком.
Одна из меньших затрат заключается в том, что блоки try / catch действительно отключают определенные оптимизации: http://msmvps.com/blogs/peterritchie/archive/2007/06/22/performance-implications-of-try-catch-finally.aspx. Полагаю, это тоже положительный момент. Его можно использовать для отключения оптимизаций, которые в противном случае могли бы нанести вред безопасным, нормальным алгоритмам передачи сообщений для многопоточных приложений, и для выявления возможных условий гонки;) Это единственный сценарий, который я могу придумать, использовать try / catch. Даже у этого есть альтернативы.