Я просто просматривал некоторый код, который написал некоторое время назад, и вижу, что у меня есть несколько частных методов, которые выдают аргументы аргументов nulllexcece и / или аргументов аргументов, если возникают проблемы с параметрами методов.
Я предполагаю, что мое обоснование заключается в том, что это помогает в будущем проверить приложение, если кто-то попытается «злоупотребить» методом в будущем. Однако, учитывая, что это частный метод, и люди, которые могут вызвать этот метод, могут видеть связанные комментарии и код, просто не нужно его выбрасывать. Это конечно не повредит иметь их, хотя это добавляет беспорядок.
Мне кажется, что эти исключения, как правило, более полезны для чего-то вроде API, который будет представлен публично.
источник
Как и все остальное, это зависит ....
Если открытые методы являются простыми обертками, которые вызывают закрытый метод (по аналогии с закрытым перегруженным методом), то может иметь смысл выдать исключение в закрытом методе вместо проверки в каждом общедоступном.
Обычно, если оно не соответствует приведенному выше определению, я бы обычно не проверял аргументы и не генерировал исключение для закрытого метода. Хотя есть и другие случаи, я обычно делаю это в приватном методе перед выполнением некоторой дорогой операции, которая может потерпеть неудачу частично, если аргументы неверны.
источник
Я понимаю, что, хотя у вопроса нет языковой метки, он, вероятно, косвенно говорит о «кофейных языках». Но для полноты картины я хотел бы упомянуть несколько расходящийся кажущийся консенсус в мире C ++.
Программисты на C ++ обычно интересуются тремя вещами:
noexcept
?В прошлом я подошел к первой проблеме, написав такой код
где
CHECK_ARGS
находится#define
d к постоянная времени компиляции поэтому компилятор может полностью устранить все аргумент коды проверки в оптимизированной сборке. (Я не говорю, что компиляция проверок - это вообще хорошая вещь, но я верю, что у пользователя должна быть возможность их компилировать.)Мне все еще нравится в этом решении то, что код проверки аргументов хорошо виден, сгруппированный в
if
. Тем не менее, второй и третий вопрос не решаются этим. Поэтому теперь я снова склоняюсь к использованиюassert
макроса для проверки аргументов.Стандарты кодирования Boost согласны с этим:
Был очень интересный доклад Джона Лакоса на CppCon'14 под названием « Защитное программирование сделано правильно» ( часть 1 , часть 2 ). В первой части своего выступления он обсуждает теорию контрактов и неопределенного поведения. Во второй части он представляет то, что я считаю очень хорошим предложением для систематической проверки аргументов. По сути, он предлагает макросы утверждений, которые позволяют пользователю выбирать, какой объем бюджета (с точки зрения использования ЦП) он готов пожертвовать библиотеке для проверки аргументов, и позволяет ли библиотека разумно использовать этот бюджет. Кроме того, пользователь также может установить глобальную функцию обработки ошибок, которая будет вызываться в случае обнаружения нарушенного контракта.
Что касается аспекта, что функция является частной, я не думаю, что это означает, что мы никогда не должны проверять ее аргументы. Мы можем больше доверять нашему собственному коду, чтобы не нарушать контракт внутренней функции, но мы также знаем, что мы тоже не идеальны. Проверка аргументов во внутренних функциях так же полезна в обнаружении наших собственных ошибок, как и в открытых функциях для обнаружения ошибок в клиентском коде.
источник
Рассмотрим следующую структуру:
Внутренняя логика. Предполагается, что эта функция вызывается с правильными параметрами и поэтому использует утверждения для проверки предварительных условий, постусловий и инвариантов для проверки вашей внутренней логики.
Пользовательский интерфейс обертка: Эта функция оборачивает внутреннюю функцию и использует InvalidArgumentExceptions для обработки ошибочных значений и сказать пользователю , чтобы исправить свои входы:
Assert(x).hasLength(4);
,Assume(y).isAlphanumeric();
,Assert(z).isZipCode();
,Assume(mailAdress).matchesRegex(regex_MailAdress);
,Reject(x).ifEmpty();
и т.д.Пакетная оболочка интерфейса: эта функция оборачивает внутреннюю функцию и использует ведение журнала, метки достоверности и статистику для обработки неправильных значений без прерывания какой-либо длительной задачи. Маркировка может быть использована позже кем-то, кто проверяет и очищает базу данных результатов.
Оболочка интерфейса командной строки: эта функция оборачивает внутреннюю функцию и снова запрашивает последний ввод.
Вы должны использовать оба - утверждения и исключения - в разных методах для разных задач. Вы должны отделить внутреннюю логику от проверки параметров. Сравните это с разделением Модель, Вид, Контроллер.
источник
Существуют более эффективные способы избежать проверки пустых ссылок: используйте контракт кода или инфраструктуру AOP, чтобы выполнить проверку за вас. Google "C # код контракта" или "postsharp".
источник