Поймать исключение, добавить данные и отбросить их - PullRequest
18 голосов
/ 27 февраля 2012

У меня есть следующий код:

try
{
   OnInitialize();
}
catch (PageObjectLifecycleException exception)
{
   exception.OldLifecycleState = CurrentLifecycleState;
   exception.RequestedLifecycleState = LifecycleState.Initialized;
   throw exception;
}

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

throw;

Но мне интересно: будет ли это правильно перебрасывать модифицированное исключение или неизмененное оригинальное?

Редактировать : В ответ на комментарии "Попробуйте и посмотрите": я новичок в C #, пришедший из C ++. В C ++ вы часто обнаруживаете неопределенное поведение в подобных случаях, и меня интересует, действительно ли то, что я хочу, - это то, как оно официально работает.

Ответы [ 4 ]

25 голосов
/ 27 февраля 2012

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

try {
    // code
}
catch(Exception e) {
    throw e;
}

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

try {
    // code
}
catch(Exception e) {
    throw;
}

Приведенный выше код при компиляции в IL вызовет rethrow. Это отличается от throw, поскольку rethrow используется, чтобы сигнализировать о том, что блок, в котором было обработано исключение, по какой-то причине решил не обрабатывать его, и поэтому следует предложить ответственность блоку захвата более высокого порядка (следующий ).

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

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

В вашем примере я хотел бы предложить, что если вам нужно добавить больше информации к исключению, у вас есть возможность создать совершенно новое исключение и вызвать его. Таким образом, вы бы использовали метод throw exception;, где «исключение» - это новое исключение, содержащее дополнительную информацию и первоначально выданное исключение.

Надеюсь, это поможет!

Джеймс

22 голосов
/ 26 ноября 2015

Вы можете добавить дополнительную информацию в данные и повторно выдать исключение с помощью throw, чтобы оно сохранило свою первоначальную форму и стек вызовов

try
{
   ...
}
catch (PageObjectLifecycleException exception)
{
   exception.Data.Add("additional data", "the additional data");
   throw;
}
9 голосов
/ 27 февраля 2012

Будет сгенерирована ссылка на измененное исключение.

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

2 голосов
/ 27 февраля 2012

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...