2016-08-15 1 views
3

Я знаю, почему я не должен использовать открытые блоки уловов так:Try/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 который doensn't (и не должен) обеспечить TheString.

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

theString = placeWhereValuesComeFrom is Subclass ? ((Subclass)placeWhereValuesComeFrom).TheString : "N/A"; 

Однако, при условии, что я не хотите рефакторировать по какой-либо причине использовать промежуточный класс, что мне здесь делать? Как я могу узнать, какие возможные исключения я должен безопасно игнорировать в блоке (-ях) catch? Как насчет других подобных ситуаций, когда нет реального способа просто «посмотреть», какие исключения могут быть выбрасываться?

+1

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

+2

Вы не «обнаруживаете», какие исключения следует игнорировать. Вместо этого вы получаете только исключения, которые вы на самом деле пишете код для обработки. Если вы не знаете, что такое исключения, тогда по определению вы не можете справиться с ними и не должны их ловить. –

+0

Я знаю, что если литая динамика не имеет соответствующего поля, это вызовет исключение. Я хочу обработать это исключение. Однако я не знаю, что это за тип исключения, и документация для динамического типа *** НЕ СКАЗАЛ МНЕ ***. Существуют и другие ситуации, когда это применимо - что они делают в них? – Yushatak

ответ

2

Единственным исключением, с которым вы должны обращаться, является сбой привязки во время выполнения; когда динамический объект не реализует TheString. Тип созданного исключения: Microsoft.System.CSharp.RuntimeBinder.RuntimeBinderException.

Так что ваш код должен быть следующим:

try 
{ 
    str = myDynamicObject.TheString; 
} 
catch (Microsoft.System.CSharp.RuntimeBinder.RuntimeBinderException) 
{ 
    //Binding failure 
    str = "N/A" 
} 
catch (... //exceptions you know TheString can throw, if any...) 
{ 
    //Handle 
} 
// any other exception you don't know how To handle...don't handle it 
+0

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

+3

@Yushatak Тогда я просто думаю, что предпосылка вашего вопроса неверна. Вы должны поймать исключения, которые вы знаете, как обращаться, и ничего другого. Если вы не знаете, какие исключения вы можете получить, то вы определенно не знаете, как с ними справиться. Либо вы используете библиотеку, документально документированную (используйте другую), либо используете библиотеку, которую вы не полностью понимаете (изучите ее, и подразделение проверит ваш код на смерть). – InBetween

+0

Это самое близкое, я доберусь до ответа. Если документация не говорит вам, вы либо должны исследовать для себя, либо перейти к альтернативе. Я бы хотел, чтобы вы могли просто выделить код, а затем задать параметр «Список возможных исключений» правой кнопкой мыши, который будет проходить через код и перечислить исключения, которые можно было бы выбросить (и если вы нажмете один, он покажет вам, где он его нашел). В этот момент вы также можете добавить несколько кнопок для добавления обработчиков для выбранных или всех исключений для сценариев, где вы можете обрабатывать каждый по-своему. – Yushatak

Смежные вопросы