Зачем пробовать блоки нужно ловить - PullRequest
5 голосов
/ 15 марта 2012

У меня есть немного кода как такового

try
{
    result.FirstName = nodes[myIdx].Attributes["ows_FirstName"].Value;
} catch { }

Теперь я не знаю до вызова этого вызова, существует ли атрибут, который я ищу ( Хороший старый ресурс ).

В результате единственный линейный способ, которым я могу написать код, который я ищу, - это как таковой.

try
{
    result.FirstName = nodes[myIdx].Attributes["ows_FirstName"].Value;
} catch { }
try
{
    result.LastName = nodes[myIdx].Attributes["ows_LastName"].Value;
} catch { }

....

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

Почему я не могу просто сделать

try { result.FirstName = nodes[myIdx].Attributes["ows_FirstName"].Value; }

Так почему мы явно вынуждены объявлять блок catch, даже если он не обрабатывается? Я уверен, что есть веская причина, но не могу решить.

РЕДАКТИРОВАТЬ: Прежде чем все начнут на меня, что глотание исключения плохо, бла-бла-бла. Мы (и я) все знаем эти аргументы, но в этом (и многих) сценариях реального мира просто нет ничего исключительного в исключении, и я ничего не могу (или не должен сделать) исправить поведение.

Ответы [ 10 ]

6 голосов
/ 15 марта 2012

Если вы хотите проглотить исключение (catch, но ничего не делать), вы должны явно сделать это.

Обычно это плохая практика, поэтому нет смысла предоставлять синтаксический ярлык.Обычно вы должны либо:

  1. Обработать исключение каким-либо образом.Это может означать:
a. Retry
b. Rethrow it (preserving the inner exception) with a more meaningful message.
c. Do it another way.
d. Log it (though logging and rethrowing might be better).
e. Other

2.Просто дайте ему пузыриться (не пытайтесь, или просто попытайтесь / наконец).

5 голосов
/ 15 марта 2012

Они не являются избыточными - у них есть определенное назначение.По умолчанию отсутствие блока catch перезапустит исключение вызывающему методу.Пустой блок catch по существу «проглатывает» исключение и позволяет программе продолжаться, не обращая внимания на то, было ли выброшено исключение;как правило, плохая практика.

в исключении просто нет ничего исключительного

может быть верно, что исключение одного типа не может быть "исключение », но это не исключение only , которое может произойти.Вы должны обработать это исключение и иметь дело с любыми другими.

Например -

Что если nodes равно нулю?Что если myIdx находится за пределами массива nodes?Любое из этих условий будет исключительным , и вы должны либо обработать их специально, либо позволить вызывающей программе обработать их и действовать соответствующим образом.

[я ничего не могу сделать (или мне нужно)сделать), чтобы исправить поведение

Возможно, вы не сможете исправить это, но вам, возможно, понадобится знать об этом.Как программа ведет себя иначе в этом случае?Записать сообщение?Поднять предупреждение?Установить значение по умолчанию?Ничего не делать может быть подходящим ответом, но весьма вероятно, не адекватным ответом на любое возможное исключение.

4 голосов
/ 15 марта 2012

Почему бы просто не проверить, не является ли предмет null?

if(nodes[myIdx].Attributes != null &&
   nodes[myIdx].Attributes["ows_FirstName"] != null) {
    /* ... your code ... */
}

Или:

if(nodes[myIdx].Attributes != null) {
   if(nodes[myIdx].Attributes["ows_FirstName"] != null) {
       /* ... your code ... */
   }
   if(nodes[myIdx].Attributes["ows_LastName"] != null) {
       /* ... your code ... */
   }
}
2 голосов
/ 15 марта 2012

Должен быть другой способ проверить, существуют ли эти Атрибуты или нет, вы не должны использовать обработку исключений для каких-то функциональных целей, код, подобный этому:

try
{
    newstring = oldString.ToString();
}
catch{}

, что вы должны сделать:*

if(oldString != null)
{
    newstring = oldString;
}

Помните, что try catch предназначен для обработки вещей, названных как 'исключение'

2 голосов
/ 15 марта 2012

Возможно, причина в том, что вы не должны ловить исключение, если вы не можете его обработать. Разрешение на try без соответствующего catch ничего не изменит, но позволит использовать худшую практику.

Что касается конкретного кода, на который вы ссылаетесь, не могли бы вы просто выполнить нулевую проверку перед попыткой доступа к индексатору?

1 голос
/ 15 марта 2012

Похоже, вы используете одну из веб-служб SharePoint, поэтому тип возвращаемого значения - это какой-то XmlElement? Я уверен, что есть способ проверить, существует ли атрибут, который дешевле, чем выбрасывать исключение.

Также вам нужен вспомогательный метод, который инкапсулирует проверку и получение данных.

1 голос
/ 15 марта 2012

На этот вопрос в значительной степени ответили: C #: если все исключения будут перехвачены

Обычно, если вы перехватываете это, вы должны что-то с этим делать, иначе неЛови.В вашем случае, почему вы не можете проверить, существует ли значение атрибута первым?

1 голос
/ 15 марта 2012

Это часть синтаксиса языка.Вы не можете try без хотя бы одного catch или finally.Нет отдельного try, только try-catch, try-finally и try-catch-finally.

Это просто неимеет смысл try некоторый код, если вы не собираетесь беспокоиться об обработке исключения (catch) или, по крайней мере, убедитесь, что какой-то последующий код всегда выполняется независимо от того, что произошло (это finally).

1 голос
/ 15 марта 2012

Блок try / catch был специально разработан для перехвата и обработки исключений, которые вызываются в вашем приложении.

Простое проглатывание исключения обычно является плохой идеей (даже если вы регистрируете исключение) идолжно быть сделано явно.

0 голосов
/ 15 марта 2012

У вас не должно быть пустых блоков catch.Это плохая практика программирования.

напоминает мне о классическом ASP On Error Resume Next

...