Я знаю, почему я не должен использовать открытые блоки catch следующим образом:
int x = 0;
try
{
x = GetXFromSomeplaceThatCanFail();
}
catch //Possibly (Exception) or (Exception e)
{
//Ignore The Failure Because We Don't Care If It Fails
}
if (x != 0) //Yes I know I can use finally blocks to do something similar, but this is just an example case
{
//Do Things With x
}
Я полностью осознаю, что это «проглотит» такие вещи, как OutOfMemoryException, что является плохой практикой и может вызвать необнаруженные сбои/неявные ошибки, которые являются ужасными вещами.
Вот почему я просматриваю свой код и убеждаюсь, что таких вещей нет. Обычно вы обращаетесь к документации того, что вы используете в блоке try, и перехватываете ожидаемые исключения, или же знаете, что определенные операции генерируют определенные исключения (например, IndexOutOfRangeException при доступе к массиву с индексом и т. д.).
Тем не менее, нет документации для проверки в нестандартных ситуациях, чтобы увидеть, какие исключения могут быть выброшены (или их трудно найти). Конкретный случай из моего собственного проекта (имена переменных стали универсальными, а код упрощен) использует динамический тип для захвата строкового поля только если оно существует или в противном случае корректно завершается с ошибкой, предоставляя в качестве результата "N/A" . Еще раз напомню, что я знаю, что это плохой код:
string theString = "Some Old Value From Previous Run/etc.";
try
{
theString = (placeWhereValuesComeFrom as dynamic).TheString;
}
catch
{
theString = "N/A";
}
В этом контексте placeWhereValuesComeFrom наследуется от BaseClass, который не предоставляет (и не должен) предоставлять TheString.
Я понимаю, что могу создать промежуточный класс, который предлагает TheString и наследуется от BaseClass, а затем наследуется от него. Тем не менее, динамическое решение было очень быстро введено в действие и хорошо работает. Если для моего конкретного сценария не будет предложено лучшее решение, я планирую добавить промежуточный класс и наследовать от него только соответствующие классы, а затем протестировать так:
theString = placeWhereValuesComeFrom is Subclass ? ((Subclass)placeWhereValuesComeFrom).TheString : "N/A";
Однако, если предположить, что я по какой-либо причине не хочу проводить рефакторинг для использования промежуточного класса, что мне здесь делать? Как я могу узнать, какие возможные исключения я должен безопасно игнорировать в блоке(ах) catch? Как насчет других подобных ситуаций, когда нет реального способа просто «поискать», какие исключения могут быть выброшены?
(Exception ex) { ex.GetType().Name }
вы получите наиболее производное имя класса для этого исключения!! - person Callum Linington   schedule 15.08.2016TheString
, либо нет. Единственное исключение, которое вам нужно обработать, — это сбой привязки, который всегда один и тот же; точный тип легко определить, просто запустив случай, который не удастся, и проверив тип исключения. Я не уверен, в чем здесь проблема. - person InBetween   schedule 15.08.2016