Catch vs Catch (Exception e) и Throw vs Throw e
Являются ли эти два примера кода одинаковыми? Catch и Catch (Exception e) имеют одинаковый вывод, и результат тоже будет таким же, если я напишу Throw или Throw e.
Главная:
try
{
A();
//B();
}
catch (Exception e)
{
Console.WriteLine("{0} exception caught.", e);
}
Код 1:
static void A()
{
try
{
int value = 1 / int.Parse("0");
}
catch (Exception e)
{
throw e;
}
}
Код 2:
static void A()
{
// Rethrow syntax.
try
{
int value = 1 / int.Parse("0");
}
catch
{
throw;
}
}
Ответы
Ответ 1
Думаю, здесь есть два вопроса.
В чем разница между throw
и throw e;
?
Я не думаю, что есть веская причина писать catch (Exception e) { throw e; }
. Это теряет исходную стеклянную структуру. Когда вы используете throw;
, исходная стоп-таблица сохраняется. Это хорошо, потому что это означает, что причину ошибки легче найти.
В чем разница между catch
и catch (Exception e)
?
Оба ваших примера одинаковы и одинаково бесполезны - они просто перехватывают исключение, а затем реконструируют его. Одно из незначительных отличий заключается в том, что первый пример будет генерировать предупреждение компилятора.
Переменная 'e' объявлена, но никогда не используется
У вас больше смысла задавать этот вопрос, если в вашем блоке catch есть какой-то другой код, который действительно делает что-то полезное. Например, вы можете записать исключение:
try
{
int value = 1 / int.Parse("0");
}
catch (Exception e)
{
LogException(e);
throw;
}
Теперь необходимо использовать первую версию так, чтобы у вас была ссылка на исключение catch.
Если ваш блок catch фактически не использует исключение, вы должны использовать вторую версию, чтобы избежать предупреждения компилятора.
Ответ 2
Если мы игнорируем предупреждение "неиспользуемая переменная", единственное время, когда существует практическая разница между
catch {...}
и
catch(Exception ex) {...}
- это когда какой-то не-С# код бросает исключение Exception
. С++ может бросать что-либо. В .NET 1.1 у вас было, чтобы использовать catch
(no (Exception ex)
) для обработки этих необычных исключений. Однако это было проблематично - не в последнюю очередь, вы не можете видеть, что было брошено! Таким образом, в .NET 2.0 и выше это заверяется по умолчанию, поэтому, даже если С++ выдает, скажем, string
- вы видите его как подкласс Exception
. Обратите внимание, что это можно отключить с помощью настройки конфигурации, но: нет. Оставьте это в покое!
Проблема throw;
vs throw ex;
уже упоминается и относится к трассировке стека. Вы можете использовать throw
в обоих случаях, в результате чего сохраняется исходная трассировка стека.