AreNotSame действительно ссылается на сравнение, тогда как AreNotEqual делает сравнение равенства.
Вы должны прочитать эту статью:
Короче говоря, throw
обычно сохраняет трассировку стека исходного сгенерированного исключения, но только если исключение не произошло в текущем кадре стека (т.е. метод).
Существует метод PreserveStackTrace
(показанный в этой статье блога), который вы используете, который сохраняет исходную трассировку стека следующим образом:
try
{
}
catch (Exception ex)
{
PreserveStackTrace(ex);
throw;
}
Но мое обычное решение - либо просто не ловить, но и перебрасывать исключения, как это (если не является абсолютно необходимым), или просто всегда генерировать новые исключения, используя свойство InnerException
для распространения исходного исключения:
try
{
}
catch (Exception ex)
{
throw new Exception("Error doing foo", ex);
}
Проблема в том, что Windows сбрасывает начальную точку стека. CLR ведет себя так, как и ожидалось - это всего лишь ограничение поддержки обработки исключений операционной системой хоста. Проблема в том, что на вызов метода может быть только один кадр стека.
Вы можете выделить свои процедуры обработки исключений в отдельный «вспомогательный» метод, который обойдёт ограничения, наложенные Windows SEH, но я не думаю, что это обязательно хорошая идея.
Правильный способ перебрасывать исключение без потери информации стека - это генерировать новое исключение и включать исходное пойманное исключение в качестве внутреннего исключения.
Трудно представить себе очень много случаев, когда вам действительно нужно это сделать. Если вы не обрабатываете исключение и просто перехватываете его, чтобы перебросить, вам, вероятно, не стоит его перехватывать.
Обычное повторное преобразование сохраняет все в трассировке стека, за исключением того, что, если существующий метод находится в трассировке стека, номер строки будет перезаписан. Это раздражающее поведение. В C #, если нужно что-то сделать в исключительном случае, но не волнует, что это за исключение, можно использовать шаблон:
Boolean ok = False; try { do_something(); ok = True; } finally { if (!ok) // An exception occurred! handle_exception(); }
Есть число, где этот шаблон очень полезен; наиболее распространенной будет функция, которая должна возвращать новый IDisposable. Если функция не вернется, одноразовый предмет должен быть очищен. Обратите внимание, что любые операторы «return» в вышеупомянутом блоке «try» должны установить ok в значение true .
В vb.net можно использовать шаблон, который функционально немного лучше, хотя одно место в коде немного странно, с шаблоном:
Dim PendingException As Exception = Nothing; Try Do_Something PendingException = Nothing ' See note Catch Ex As Exception When CopyFirstParameterToSecondAndReturnFalse(Ex, PendingException ) Throw ' Will never execute, since above will return false Finally If PendingException IsNot Nothing Then .. Handle exception EndIf End Try
Функция с длинным именем должно быть реализовано очевидным образом. Этот шаблон имеет то преимущество, что делает исключение доступным для кода. Хотя это часто не требуется в ситуациях с обработкой, но не перехвата, есть одна ситуация, когда она может быть неоценимой: если процедура очистки выдает исключение. Обычно, если процедура очистки выдает исключение, любое ожидающее исключение будет потеряно. Однако с помощью приведенного выше шаблона можно заключить ожидающее исключение в исключение очистки.
Одна интересная заметка с приведенным выше кодом: исключение может достигнуть «Catch When», но оператор Try может завершиться нормально. На самом деле не совсем ясно, что должно происходить в таких обстоятельствах, но ясно одно: утверждение «Окончание» не должно действовать так, как если бы исключение находилось на рассмотрении. Очистка PendingException сделает так, что если исключение исчезнет, код будет вести себя так, как будто этого никогда не было. В качестве альтернативы можно заключить в оболочку и выбросить исключение, о котором известно, что оно произошло, поскольку эта ситуация почти наверняка указывает на что-то не так с внутренним кодом обработки исключений.