разница между броском и броском нового исключения ()

Я не вижу, как вы можете прямо установить один обработчик для всех сигналов. Однако вы можете получить справедливо закройте с помощью sigfillset() , чтобы сгенерировать набор, содержащий все допустимые номера сигналов, а затем перебрать возможные номера сигналов с помощью sigismember() , чтобы определить, находится ли это число в наборе и, если да, установите обработчик. Хорошо, я не вижу метода определения того, что такое максимально возможный номер сигнала, поэтому вам, возможно, придется угадать подходящее максимальное значение.

150
задан Dirk Vollmar 8 June 2010 в 16:34
поделиться

8 ответов

throw; повторно генерирует исходное исключение и сохраняет исходную трассировку стека.

throw ex; генерирует исходное исключение, но сбрасывает трассировку стека, уничтожая всю информацию трассировки стека до вашего блока catch .


НИКОГДА не пишите throw ex;


throw new Exception (ex.Message); еще хуже. Он создает новый экземпляр Exception , теряя исходную трассировку стека исключения, а также его тип. (например, IOException ).
Кроме того, некоторые исключения содержат дополнительную информацию (например, ArgumentException.ParamName ).
throw new Exception (ex.Message); также уничтожит эту информацию.

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

Для этого определите новый класс, который наследует Exception , добавьте все четыре конструктора исключений и, необязательно, дополнительный конструктор, который также принимает InnerException . в качестве дополнительной информации и сгенерируйте новый класс исключения, передав ex в качестве параметра InnerException . Передав исходное InnerException , вы сохраните все свойства исходного исключения, включая трассировку стека.

250
ответ дан 23 November 2019 в 21:50
поделиться

throw повторно генерирует перехваченное исключение, сохраняя трассировку стека, в то время как throw new Exception теряет некоторые детали перехваченного исключения.

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

У BlackWasp есть хорошая статья под названием Выдача исключений в C # .

4
ответ дан 23 November 2019 в 21:50
поделиться

Ваш второй пример сбросит трассировку стека исключения. Первый пример наиболее точно сохраняет происхождение исключения. Также вы разворачиваете исходный тип, что является ключевым для понимания того, что именно пошло не так... Если второй способ необходим для функциональности - например, для добавления расширенной информации или повторного разворачивания со специальным типом, таким как пользовательский 'HandleableException', то просто убедитесь, что свойство InnerException тоже установлено!

0
ответ дан 23 November 2019 в 21:50
поделиться

Самое важное отличие состоит в том, что второе выражение стирает тип исключения. И тип исключения играет жизненно важную роль в перехвате исключений:

public void MyMethod ()
{
    // both can throw IOException
    try { foo(); } catch { throw; }
    try { bar(); } catch(E) {throw new Exception(E.message); }
}

(...)

try {
    MyMethod ();
} catch (IOException ex) {
    Console.WriteLine ("Error with I/O"); // [1]
} catch (Exception ex) {
    Console.WriteLine ("Other error");    // [2]
}

Если foo () выбрасывает IOException , [1] блок catch перехватит исключение. Но когда bar () выбрасывает IOException , оно будет преобразовано в обычное Exception и не будет поймано блоком захвата [1] .

0
ответ дан 23 November 2019 в 21:50
поделиться

Первый сохраняет исходную трассировку стека:

try { ... }
catch
{
    // Do something.
    throw;
}

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

try { ... } catch (Exception e)
{
    throw new BarException("Something broke!");
}

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

try { ... }
catch (FooException e) {
    throw new BarException("foo", e);
} 

Я бы рекомендовал использовать:

  • первый, если вы хотите выполнить некоторую очистку в ситуации ошибки, не уничтожая информацию или не добавляя информацию об ошибке.
  • третий, если вы хотите добавить дополнительную информацию об ошибке.
  • второй, если вы хотите скрыть информацию (от недоверенных пользователей).
30
ответ дан 23 November 2019 в 21:50
поделиться

Бросок нового исключения уничтожает текущую трассировку стека.

throw; сохраняет исходный след стека и почти всегда более полезен. Исключением из этого правила является случай, когда вы хотите обернуть Исключение в собственное Исключение. Тогда вам следует сделать следующее:

catch(Exception e)
{
    throw new CustomException(customMessage, e);
}
4
ответ дан 23 November 2019 в 21:50
поделиться

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

Использование throw без аргументов сохраняет стек вызовов для целей отладки.

3
ответ дан 23 November 2019 в 21:50
поделиться

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

0
ответ дан 23 November 2019 в 21:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: