Пустые блоки catch

Я иногда столкнетесь с ситуациями, где мне нужно, чтобы поймать исключение, если это'ы никогда не бросали, но не делать ничего с ним. Другими словами, исключение может произойти, но это вовсе'т имеет значения, если он делает.

Я недавно прочитала статью о подобное: http://c2.com/cgi/wiki?EmptyCatchClause

Этот человек рассказывает о том, как комментируют

// should never occur 

запах код не должен появляться в коде. Затем они идут на объясните, как комментировать

// don't care if it happens

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

var addressCollection = new MailAddressCollection();
foreach (string address in addresses)
{
    try
    {
        addressCollection.Add(address);
    }
    catch (Exception)
    {
        // Do nothing - if an invalid email occurs continue and try to add the rest
    }
}

Теперь, вы можете думать, что это плохая идея, так как вы бы хотели, чтобы вернуться к пользователю и объяснять, что одно или несколько сообщений не могут быть отправлены получателю. Но что, если это's просто чч адрес? Что's не менее важно и вы все равно хотите отправить сообщение, даже если один из этих адресов был неверный (возможно, просто опечатка).

Я же правильно использовать пустой блок catch или есть лучшая альтернатива, что я'м не в курсе?

Комментарии к вопросу (6)
Решение

Вы совершенно правы, чтобы использовать пустой блок catch, если вы действительно хотите, чтобы ничего не делать, когда возникает определенный тип исключения. Вы могли бы улучшить ваш пример, ловя только те типы исключений, которые вы ожидаете* чтобы произойти, и которые вы знаете, являются безопасными, чтобы игнорировать. Поймав "исключение", можно скрыть ошибки и сделать его более трудным для себя, чтобы отладить программу.

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

Для 2-й (ошибка программирования), было бы большой ошибкой просто на "Ласточка" не исключение. Лучшая вещь, чтобы сделать, это, как правило, для журнала трассировки стека, а затем появляется сообщение об ошибке, говорящее пользователю, что произошла внутренняя ошибка произошло, и что они должны отправить свои логи разработчикам (т. е. вы). Или во время разработки, вы можете просто сделать это печать трассировки стека в консоли и сбой программы.

Для 1-й (внешняя проблема), нет правила о том, что в "Правый" и что не должен делать. Все зависит от деталей заявки. Если вы хотите игнорировать определенного состояния и дальше, то сделай так.

ВООБЩЕ:

Это's хорошо, что Вы читаете технические книги и статьи. Вы можете многому научиться от этого. Но, пожалуйста, вспомните, как Вы читаете, вы найдете много советов от людей, говорящих, что делаешь то-то и то-то всегда неправильная или всегда прав. Часто эти мнения граничат с религией. Не считаю, что делать вещи определенным образом, абсолютно и"Право и" потому что книги или статьи (или ответ на так... &ЛТ;кашель&ГТ;) тебе так сказала. Есть исключения к каждому правилу, и люди, пишущие эти статьи, Дон'т знать детали вашей заявки. Вы. Убедитесь, что Вы читаете имеет смысл, и если это не'т доверять себе.

Комментарии (3)

Пустой блок catch-это нормально в нужном месте - хотя из вашего образца я бы сказал, Вы должны cetagorically **** не использовать поймать (исключение). Вместо этого вы должны поймать явные исключения, которые вы ожидаете, произойдет.

Причиной этого является то, что если вы проглотите все, вы будете глотать критических дефектов, что вы были'т ожидать, слишком. Там'ы огромная разница между "Я могу'т отправить на этот адрес электронной почты" и "вашем компьютере не хватает места на диске." Вы не'т хотим, чтобы продолжать пытаться отправить на следующий 10000 писем, Если вы're вне дискового пространства!

Разница между "и не должно происходить" и "Дон'т волнует, если это случится" это то, если ее "не должно" тогда, когда он не произошло, вы не'т хотим, чтобы это проглотить молча! Если это'ы условие, вы никогда не ожидается, вы обычно хотите, чтобы ваше приложение к краху (или по крайней мере завершить чисто и журналов обильно, что'ы и произошло), так что вы можете определить это невыполнимое условие.

Комментарии (2)

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

Если есть конкретные сценарии, которые могут привести к сбою, что вы не против, то вы должны поймать и теста для этих конкретных сценариев и выдали во всех остальных случаях, например

foreach (string address in addresses)
{
    try
    {
        addressCollection.Add(address);
    }
    catch (EmailNotSentException ex)
    {
        if (IsCausedByMissingCcAddress(ex))
        {
            // Handle this case here e.g. display a warning or just nothing
        }
        else
        {
            throw;
        }
    }
}

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

Комментарии (4)

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

Часто эти методы будут иметь префикс "попробовать" перед ними. Вместо того, чтобы бросать исключение функция возвращает логическое значение, указывающее, если задача выполнена успешно.

Хорошим примером этого является разбор против метод tryparse

string s = "Potato";
int i;
if(int.TryParse(s, out i))
{
    //This code is only executed if "s" was parsed succesfully.
    aCollectionOfInts.Add(i);
}

Если описанные выше функции в цикле и сравнить его с разбора + поймать equilvilant метод tryparse будет гораздо быстрее.

Комментарии (2)

Используя пустой блок catch просто глотает исключения, я всегда справлюсь, даже если это доложить вам, что "исключение" произошло.

Также ловить исключение универсального `порочная практика связана с тем, что он может скрывать ошибки в приложении. Например, вы поймали себя ArgumentOutOfRange исключение, которое вы не поняли, что происходит, а затем проглотил ее (т. е. ничего не делал с ним).

Комментарии (0)