Разница между Catch (Exception) и Catch(Exception ex)

в чем разница между Catch(Exception) и Catch(Exception ex) . Я вижу, что оба дают мне ожидаемый результат. Тогда в чем же разница? Что рекомендуется ?

предположим, что код ниже.

int a = 1, b = 0;
try
{
    int c = a / b;
    Console.WriteLine(c);
}

какой из приведенных ниже блоков catch рекомендуется использовать ? В чем фактическая разница между ними ?

catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

или

catch (Exception)
{
    Console.WriteLine("Oh NO!!");
}

6 ответов


Ну catch(Exception ex) аналогично catch(Exception) С одной разницей только в catch(Exception ex) у нас есть доступ к классу исключений (причина ошибки ) пример. Обычно для печати оригинала требуется экземпляр класса exception сообщение:

  try {
    ...
  }
  catch (AppServerException e) {
    Console.WriteLine("Application server failed to get data with the message:");
    Console.WriteLine(e.Message); // <- What's actually got wrong with it
  }

Если вам не нужен экземпляр класса исключений, например, вы планируете просто использовать исключение, синтаксис catch(Exception ex) является чрезмерным, а catch (Exception prefferable:

  try {  
    c = a / b;
  }  
  catch (DivideByZeroException) {
    c = Int.MaxValue; // <- in case b = 0, let c be the maximum possible int
  }

наконец-то. не поймать общий класс исключений без повторного прохождения:

  try {
    int c = a / b;
  }
  catch (Exception) { // <- Never ever do this!
    Console.WriteLine("Oh NO!!");
  }

вы действительно хотите кодировать " любую ошибку (зеленый дым от процессора в комплекте) happend просто распечатать "О нет"и продолжить"? Шаблон с классом Exception что-то вроде этого:

  tran.Start();

  try {
    ...
    tran.Commit();
  }
  catch (Exception) {
    // Whatever had happened, let's first rollback the database transaction
    tran.Rollback();

    Console.WriteLine("Oh NO!");

    throw; // <- re-throw the exception
  }

Это довольно просто:

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

Что использовать на самом деле зависит от того, сколько информации вы хотите иметь об исключении поднял.


Если вам нужно использовать исключение внутри catch блок, дать Exception имя; в противном случае, сохранить его анонимность.

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

catch (ConnectToServerException cse) {
    MessageBox.Show(string.Format(
        "Connection to server '{0}' failed. Use a name from the following list: {1}"
    ,   cse.AttemptedConnectionServerName
    ,   string.Join(", ", cse.AllowedServerNames)
    ));
}

приведенный выше код предполагает, что пользовательские исключения ConnectToServerException есть свойство AttemptedConnectionServerName С именем сервера, к которому вы пытались подключиться, и свойством перечисления AllowedServerNames С именами доступных серверов.

есть также ситуации, когда все, что вам нужно знать, это то, что только что произошло исключение определенного типа. В этом случае вам не нужно предоставлять им переменную.


С catch(Exception) вы только указываете, какое исключение вы собираетесь обрабатывать в этом блоке catch (в этом случае любое исключение, которое возникает, поэтому оно будет таким же, как просто catch)

С catch(Exception ex) вы передаете экземпляр фактического исключения, которое возникает, поэтому вы можете получить доступ к свойствам исключения и сделать что-то с предоставленной информацией.


Catch (Exception) сделайте то же самое, так как это также Exception тип.

Catch (Exception ex) ловит все исключения и, кроме того, вы можете получить сообщение через ссылку.

использование зависит от требования, если вы хотите показать сообщение об исключении у вас есть возможность использовать ex.Message иначе Catch (Exception) будет достаточно.


разница в том, что один будет печатать попытка деления на ноль. а другой напечатает О нет!!.

обработка исключений является сложной проблемой и зависит от приложения, но вот несколько общих замечаний:


вообще говоря, лучше всего предоставить обработчики для конкретных исключений:

что-то типа:

 catch ({System.DivideByZeroException ex )
 {
    Console.WriteLine("Ops. I cannot divide by zero." );
 }
 catch ({System.Exception ex )
 {
    Console.WriteLine("There was an error during calculations: {0}", ex.Message );
 }

рано или поздно вы найдете то, что Console.WriteLine просто не достаточно хорошо, и вам придется использовать лесопогрузчик, чтобы начать использовать его рано.


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

что-то типа:

 catch ({System.DivideByZeroException ex )
 {
    Console.WriteLine("Oops. I cannot divide by zero." );
 }
 catch ({System.Exception ex )
 {
    Console.WriteLine(GetExceptionMsgs(ex));
 }

 ...in another class...
public static string GetExceptionMsgs(Exception ex) {
   if( ex == null ) {
       return "No exception = no details";
   }
   var sb = new StringBuilder();
   while( ex != null ) {
        sb.AppendLine(ex.Message);
        ex = ex.InnerException;
   }
   return sb.ToString()
}