Разница между уловкой (исключение), catch() и просто уловом
Я хочу знать, могу ли я безопасно писать catch() только для того, чтобы поймать все типы System.Exception. Или я должен придерживаться catch (Exception), чтобы выполнить это. Я знаю, что для других типов исключений (например, InvalidCastException) я должен указать тип как catch (InvalidCastException). Другими словами, я спрашиваю, являются ли следующие образцы кода одинаковыми.
Это...
try
{
//do something
}
catch(Exception)
{
//handle exception
}
это...
try
{
//do something
}
catch() //Causes compile time error "A class type expected"
{
//handle exception
}
и это...
try
{
//do something
}
catch
{
//handle exception
}
update: В моем вопросе была ошибка. не разрешено в С#.
Ответы
Ответ 1
В идеальном мире вы не должны использовать catch(Exception)
и catch
(в одиночку) вообще, потому что вы никогда не должны улавливать общее исключение Exception
. Вы всегда должны улавливать более конкретные исключения (например, InvalidOperationException
... и т.д.).
В реальном мире как catch(Exception)
, так и catch
(в одиночку) эквивалентны. Я рекомендую использовать catch(Exception ex)
, когда вы планируете повторно использовать только переменную исключения, и catch
(отдельно) в других случаях. Просто вопрос стиля для второго варианта использования, но если лично найти его более простым.
Что действительно важно (даже если это выходит за рамки вашего вопроса) заключается в том, что вы никогда не пишете следующий фрагмент кода:
try
{
}
catch (SpecificException ex)
{
throw ex;
}
Это будет reset трассировка стека до точки броска. С другой стороны:
try
{
}
catch (SpecificException)
{
throw;
}
сохранить исходную трассировку стека.
Ответ 2
Обе конструкции (catch ()
являются синтаксической ошибкой, как указано в sh4nx0r) ведут себя одинаково в С#. Тот факт, что оба разрешены, вероятно, является языком, унаследованным от синтаксиса С++.
Другие языки, включая С++/CLI, могут throw
объекты, которые не происходят из System.Exception
. В этих языках catch
будет обрабатывать те исключения, отличные от CLS, но catch (Exception)
не будет.
Ответ 3
catch(Exception ex)
может обрабатывать все исключения, которые получены из класса System.Exception
, однако, если выведенное исключение не получено из System.Exception
, то оно не будет обрабатываться catch(Exception ex)
.
До исключения .NET 3.0, созданного небезопасным кодом (то есть код, не предназначенный для CLR), обрабатывались catch{}
. После .NET Framework 3.0 все типы исключений могут обрабатываться классом System.Exception
. catch{}
теперь устарел.
Ответ 4
Взгляните на эту ссылку:
http://msdn.microsoft.com/en-gb/library/0yd65esw.aspx
Я думаю, что все будет хорошо, есть или нет, но вы можете позволить аргументу в catch catch получить именно то исключение, которое вы хотите, и обработать их правильно.
Ответ 5
Если тот факт, что возникает исключение, подразумевает, что вам нужно запустить кусок кода, но вы ничего не сделали бы с исключением, кроме повторного его, если вы его поймали, предпочтительный подход, вероятно, не поймать исключение, но вместо этого сделайте что-то вроде:
bool ok=false;
try
{
... do stuff -- see note below about 'return'
ok = true;
}
finally
{
if (!ok)
{
... cleanup code here
}
}
Единственным недостатком этого шаблона является то, что нужно вручную добавить ok = true;
перед любым оператором return, который встречается в блоке try
(и гарантировать, что не может возникнуть исключение (отличное от ThreadAbortException) между ok = true;
и возврат). В противном случае, если кто-то не собирается делать ничего с исключением, его не следует ловить.