Разница между беззазорным уловом и другим уловом

У меня есть фрагмент кода

//Code 1 Code 2 Code 3
try try try
{ { {
 //Exp occur //Exp occur //Exp occur 
} } }
catch (Exception e) catch (Exception) catch
{ { {
 //Handle exp //Handle exp //Handle exp
} } }

В чем разница между всеми тремя кодами PS Я новичок в C# и насколько это касается Java или Objective-C этот синтаксис вызывает ошибку

7 ответов

Код 1

Его захватывающее исключение в объекте e, которое позднее может использоваться для обработки исключений. Например, вы можете зарегистрировать свойство Message или просмотреть трассировку стека с помощью e.Message или e.StackTrace

Код 2

Вы избегаете исключения базового типа Exception, но поскольку у вас нет какого-либо объекта, связанного с ним, вы можете просто выбросить это исключение, чтобы оно могло пузыриться или вы могли игнорировать исключение. Если в этом коде у вас был:

catch(InvalidCastException)

Затем все InvalidCastException будут обрабатываться в блоке без объекта исключения

Код 3

Вы заражаете все типы исключений независимо от их типа, который похож на ваш код 2 с базовым классом Exception

try-catch - MSDN

Хотя предложение catch может использоваться без аргументов, чтобы поймать тип исключения, это использование не рекомендуется. В общем, вы следует только поймать те исключения, о которых вы знаете, как их восстановить.

Всегда лучше, если вы поймаете определенные исключения, прежде чем поймать базовый. Что-то вроде.

try
{
}
catch(InvalidCastException ex)
{
}
catch(Exception ex)
{
}

try-catch - MSDN

В одном и том же try-catch. В этом случае порядок предложений catch важно, потому что предложения catch рассматриваются в порядке. Поймать более конкретные исключения перед менее конкретными. Компилятор выдает ошибку, если вы заказываете блоки catch, чтобы более поздний блок никогда не может быть достигнуто.


Код 1 - довольно нормальный улов, надеюсь, не нуждается в объяснении

Код 2 - Вы хотите выполнить конкретный фрагмент кода, когда возникает конкретное исключение, но вы не намерены фактически взаимодействовать с объектом исключения. В конце концов, почти всегда есть оператор throw;, так что кто-то еще выше по стеку, который заботится, может catch его.

Код 3 - Вы хотите, чтобы код выполнялся для любого исключения (*) (за исключением тех, которые были уловлены ранее catch предложениями того же try). Опять же, почти всегда нужно включать throw;, чтобы более высокий код мог catch и фактически обрабатывать исключение.

На некотором уровне (возможно, только на верхнем уровне, в обработчиках необработанных исключений для любой среды, в которой вы находитесь), что-то должно проверять объект исключения и, возможно, регистрировать его (если это возможно).


Здесь, если вы хотите использовать переменную 'e' для получения сообщения Exception, Line или type.

//Code 1 
try 
{ 
 //Exp occur 
} 
catch (Exception e) 
{ 
 //Handle exp 
}

Ниже приведен код для получения определенного типа Exception и не относящийся к переменной Exception.

//Code 2
try 
{ 
 //Exp occur 
} 
catch (Exception)
{ 
 //Handle exp 
}

Ниже код захватывает все типы исключений.

//Code 3
try
{
 //Exp occur 
} 
catch 
{ 
 //Handle exp 
}


Ничего. Все они улавливают КАЖДОЕ исключение, которое может произойти (путем улова базового типа Exception или просто любого). Это, как правило, неодобрительно. Вы должны поймать определенные исключения в ожидаемом порядке, а затем, если вы хотите поймать все исключения catch Exception в конце.

try
{
}
catch (MyCustomException)
{
 // do something for your custom exception
}
catch (Exception)
{
 // do something for everything else
}

Когда вы укажете переменную для своего исключения, например catch (Exception e), вы получите доступ к трассировке стека (и другой информации об исключении) через e.Property или просто e.ToString() для полного сообщения. Также лучше всего использовать throw исключение при захвате (ну, если вы не хотите его подавить на этом уровне и не позволяете вашему коду вызова видеть исключение), поэтому он пузырится и сохраняет трассировку стека:

catch (Exception e)
{
 // do something with e
 throw;
}


если вы планируете фактически использовать объект исключения, зарегистрировать его свойства в файле журнала или показать окно сообщения или выбросить другой вид исключения и передать текущее исключение его конструктору, тогда вы должны использовать первый из три (самый левый).

в общем случае наиболее используемый подход в любом случае является первым, если вы хотите обрабатывать разные исключения отдельно, вы можете иметь несколько блоков catch, начиная с наиболее специализированных сверху и иметь тот, который вы написали внизу, чтобы все исключения, которые уже не обрабатываются, заканчиваются в общем блоке catch.


Код 1 ловит каждое исключение (в вашем случае!) и объявляет его, поэтому вы можете использовать его позже, например. для сообщений об ошибках.

MessageBox.Show(e.Message);

Код 2 также ловит каждое исключение (в вашем случае!), но вы не можете его использовать, потому что он не объявлен.

Эти два метода не предназначены для этого, они предназначены для обнаружения конкретных или пользовательских исключений.

try
 {
 //mycode
 }catch(MyException myExc)
 { 
 //TODO HERE 
 Console.Write(myExc.Message); 
 }

Третий выбирает все исключения. Потому что нет определения.

Взгляните на: http://msdn.microsoft.com/de-de/library/0yd65esw%28v=vs.80%29.aspx

чтобы узнать больше об исключениях на С#.


Отличия:

  • Объявление параметра исключения ex позволяет вам получить доступ к объекту Exception, чтобы видеть и работать со своими свойствами, полями, методами и т.п. Эта переменная "ex" работает как любой параметр в любом методе.

  • Объявление типа исключения без параметра ex позволяет отделить несколько областей "catch" для разных типов исключений. Это бесполезно и функционально эквивалентно образцу кода 3, как вы его определяете здесь, но если вам нужно выполнять разные действия в зависимости от типа исключения, и вам не нужно обращаться к объекту исключения (вам нужно знать только тип исключения), то это ваш путь.

  • Обработчик Untyped Catch Exception позволяет вам добавить резерв для любого Исключения, которое может быть выбрано, независимо от его типа. Однако, поскольку он не параметризирован, у вас не будет доступа к свойствам или методам объекта Exception. Таким образом, оба примера кода 2 и пример кода 3 являются эквивалентными.

Пример:

try{ // code that throws exception }
catch(TypeException ex) 
{ 
 // code to handle exceptions of type TypeException
 // I can access ex parameter, for example to show its Message property
 MessageBox.Show(ex.Message);
}
catch(OtherTypeException) 
{ 
 // code to handle exceptions of type OtherTypeException 
 // I cannot access the ex parameter since it is not declared, but I know
 // the exact type of the exception
 MessageBox.Show("There was an exception of Other Type");
}
catch
{
 // code to handle any other exception
 // this is functionally equivalent to catch(Exception) since all typed exceptions
 // inherit from the base type Exception
 MessageBox.Show("An unknown exception has been thrown.");
}
...

licensed under cc by-sa 3.0 with attribution.