Подтвердить что ты не робот

Разница между уловкой (исключение), 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: В моем вопросе была ошибка. не разрешено в С#.

4b9b3361

Ответ 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; и возврат). В противном случае, если кто-то не собирается делать ничего с исключением, его не следует ловить.