Проверка аргументов метода
От: INsideR Латвия  
Дата: 24.08.09 14:13
Оценка:
Поделитесь опытом, как лучше проверять аргументы метода на допустимость значений, с помощью assert(и проверка только в debug сборке) или с помощью кода (if(...)throw).
Мудр тот, кто знает не многое, а нужное
Re: Проверка аргументов метода
От: Andir Россия
Дата: 24.08.09 14:25
Оценка: 21 (3) +2
Здравствуйте, INsideR, Вы писали:

INR>Поделитесь опытом, как лучше проверять аргументы метода на допустимость значений, с помощью assert(и проверка только в debug сборке) или с помощью кода (if(...)throw).


Code Contracts
.Net Version |
< 4.0 — Code Contracts library,
>= 4.0 — Встроенные средства.

С Уважением, Andir!
Re: Проверка аргументов метода
От: Пельмешко Россия blog
Дата: 24.08.09 14:26
Оценка: 1 (1)
Здравствуйте, INsideR, Вы писали:

INR>Поделитесь опытом, как лучше проверять аргументы метода на допустимость значений, с помощью assert(и проверка только в debug сборке) или с помощью кода (if(...)throw).


Если Вы пишете бибилиотеку, то логично будет в публичных методах (public surface) делать проверки в стиле if-then-throw, а вот внутри уже можно и ассертами, если уверены и тестировать дебаг-билд будете хорошо
Re: Проверка аргументов метода
От: TK Лес кывт.рф
Дата: 24.08.09 14:27
Оценка: 1 (1) +2
Здравствуйте, INsideR, Вы писали:

INR>Поделитесь опытом, как лучше проверять аргументы метода на допустимость значений, с помощью assert(и проверка только в debug сборке) или с помощью кода (if(...)throw).


Обычно, в private методах стоят assert'ы, а в public не-assert'ы. мотивация простая — как будут использовать public метод не известно. а вот private метод используется только "изнутри" и передавать самому себе некорректные данные смысла мало...
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re: Проверка аргументов метода
От: bnk СССР http://unmanagedvisio.com/
Дата: 24.08.09 14:58
Оценка:
Здравствуйте, INsideR, Вы писали:

INR>Поделитесь опытом, как лучше проверять аргументы метода на допустимость значений, с помощью assert(и проверка только в debug сборке) или с помощью кода (if(...)throw).


В дебаге — ассерты, в релизе — лог + что-то "по смыслу" типа "return false" или там исключения (если есть уверенность что его поймают), т.е. лишь бы прога не упала
Re[2]: Проверка аргументов метода
От: hexamino http://hexamino.blogspot.com/
Дата: 24.08.09 15:33
Оценка:
Здравствуйте, bnk, Вы писали:

bnk> или там исключения (если есть уверенность что его поймают), т.е. лишь бы прога не упала


Да-да, если что-то пошло не так, пускай нарушает целостность данных или сообщает пользователю неверные данные о его транзакциях — лишь бы только не упала, чтобы тестировщики ничего не заметили...
Re[3]: Проверка аргументов метода
От: bnk СССР http://unmanagedvisio.com/
Дата: 24.08.09 15:47
Оценка:
Здравствуйте, hexamino, Вы писали:

bnk>> В дебаге — ассерты, в релизе — лог + что-то "по смыслу", лишь бы прога не упала


H>Да-да, если что-то пошло не так, пускай нарушает целостность данных или сообщает пользователю неверные данные о его транзакциях — лишь бы только не упала, чтобы тестировщики ничего не заметили...


Это ты о ком?
Добрее надо быть к людям, они к тебе и потянутся (c)
Re: Проверка аргументов метода
От: Legion13  
Дата: 24.08.09 16:28
Оценка: 3 (1)
Здравствуйте, INsideR, Вы писали:

INR>Поделитесь опытом, как лучше проверять аргументы метода на допустимость значений, с помощью assert(и проверка только в debug сборке) или с помощью кода (if(...)throw).


Пользуюсь утилитным классом, с методами наподобие

[AssertionMethod]
public static void ArgumentNotNull(
    [AssertionCondition(AssertionConditionType.IS_NOT_NULL)] object argumentValue,
    [NotNull] string argumentName)
{
    if (null == argumentValue)
    {
        ArgumentNotNull(argumentName, "argumentName");

        string fmtAssert = string.Format(ASSERT_ARGUMENT_NOT_NULL_FMT, argumentName);
        Debug.Fail(fmtAssert);
        throw new ArgumentNullException(argumentName);
    }
}




[AssertionMethod]
public static void ArgumentCondition([NotNull] Func<bool> condition, [NotNull] string errorMessage)
{
    ArgumentNotNull(condition, "condition");

    bool result = condition.Invoke();
    if (!result)
    {
        ArgumentNotNull(errorMessage, "errorMessage");
        Debug.Fail(errorMessage);
        throw new ArgumentException(errorMessage);
    }
}



[AssertionMethod]
public static void ArgumentNotNullOrEmptyString(
    [AssertionCondition(AssertionConditionType.IS_NOT_NULL)] string argumentValue,
    [NotNull] string argumentName)
{
    ArgumentNotNull(argumentValue, argumentName);

    if (0 == argumentValue.Length)
    {
        ArgumentNotNull(argumentName, "argumentName");

        string fmtAssert = string.Format("{0}: {1}", STRING_CANNOT_BE_EMPRY, argumentName);
        Debug.Fail(fmtAssert);
        throw new ArgumentException(STRING_CANNOT_BE_EMPRY, argumentName);
    }
}


т.е. в Debug-версии будут срабатывать assert'ы, а в Release-версии — исключения.
Re[3]: Проверка аргументов метода
От: andy1618 Россия  
Дата: 24.08.09 18:11
Оценка: 40 (2) +1
Здравствуйте, hexamino, Вы писали:

bnk>> или там исключения (если есть уверенность что его поймают), т.е. лишь бы прога не упала


H>Да-да, если что-то пошло не так, пускай нарушает целостность данных или сообщает пользователю неверные данные о его транзакциях — лишь бы только не упала, чтобы тестировщики ничего не заметили...


В "Совершенном коде" автор посвятил этой проблеме отдельный раздел.
Вкратце: единого решения нет, и точку на линии "целостность — устойчивость" приходится
выбирать, исходя из предметной области.
Примеры:
1) Программа для вычисления дозы лекарства, вводимого пациенту через капельницу.
Тут, понятное дело, должна быть стратегия "отваливаться при любой мало-мальской ошибке".
2) Алгоритм переноса строк в текстовом редакторе. Здесь всё наоборот — уж лучше пусть
криво слова переносит, чем будет падать с потерей набранного текста
Те, кто много работает с Вордом, наверняка помнят остроту ощущений, когда на экране появляется
сообщение, что приложение выполнило недопустимую операцию и будет закрыто
Re[4]: Проверка аргументов метода
От: IT Россия linq2db.com
Дата: 25.08.09 03:50
Оценка:
Здравствуйте, andy1618, Вы писали:

A>1) Программа для вычисления дозы лекарства, вводимого пациенту через капельницу.

A>Тут, понятное дело, должна быть стратегия "отваливаться при любой мало-мальской ошибке".

Точно, пусть сразу отваливается, а заодно и дыхательный аппарат отключает.

A>2) Алгоритм переноса строк в текстовом редакторе. Здесь всё наоборот — уж лучше пусть

A>криво слова переносит, чем будет падать с потерей набранного текста

Пусть хоть криво — это часть алгоритма, а не исключительная ситуация.

В общем, оба примера мимо.
//rsdn.org/forum/images/bis.gif Если нам не помогут, то мы тоже никого не пощадим.
Re[5]: Проверка аргументов метода
От: bnk СССР http://unmanagedvisio.com/
Дата: 25.08.09 04:15
Оценка:
Здравствуйте, IT, Вы писали:

IT>Пусть хоть криво — это часть алгоритма, а не исключительная ситуация.


Ну тут AFAIU как бы речь о том, что делать, если "программа поняла, что она работает неправильно"
То есть, что "случилось страшное". Варианты:

— Умереть с тоски.
— Попробовать все же что-то сделать в этих обстоятельствах.

Мне кажется, что в дебаг-версии (для отладки или тестирования) первый вариант предпочтительнее.
Для пользователя же наверняка окажется более приятным второй вариант.
Re[6]: Аналогия
От: bnk СССР http://unmanagedvisio.com/
Дата: 25.08.09 05:03
Оценка: 1 (1) :))) :))
Кстати, такой вот пример. Возьмем например человека, который понял, что в его жизни что-то идет не так.
Ну например ему стукнул тридцатник, а у него ни кола ни двора ни определенной цели
Также два варианта:

— Убить себя об стену.
— Попытаться как-то выйти из этого положения.

Если бы это была отладочная версия, то первый вариант определенно выигрывает.
А так, второй вариант выглядит предпочтительнее.

Re: Проверка аргументов метода
От: _FRED_ Черногория
Дата: 25.08.09 05:12
Оценка:
Здравствуйте, INsideR, Вы писали:

INR>Поделитесь опытом, как лучше проверять аргументы метода на допустимость значений, с помощью assert(и проверка только в debug сборке) или с помощью кода (if(...)throw).


Я не делаю различий — паблик-не паблик, аргументы проверяю if-throw. Потому что [мне] проще написать так, чем думать: вот это мы проверяем здесь, да и при рефакторинге дело упрощает, когда приходится менять область видимости метода.

Ассерты ставлю при проверке инвариантов состояния класса или локальных переменных.

CodeContract-ы, к сожалению, в рабочем проекте не используются, а то обошёлся бы ими. Но их тоже надо ещё "научиться готовить", ИМХО, не такой это простой велосипед, на который "сел и поехал"
Help will always be given at Hogwarts to those who ask for it.
Re[5]: Проверка аргументов метода
От: andy1618 Россия  
Дата: 25.08.09 05:12
Оценка: 39 (2)
Здравствуйте, IT, Вы писали:

IT>В общем, оба примера мимо.


Примеры не совсем точные, приводил по памяти. На всякий случай — вот точные цитаты
(Макконнелл С. "Совершенный код. Мастер-класс" / Пер. с англ. — М.: Издетальство "Русская Редакция", 2007.)

с.189

Иногда наилучшей реакцией на неправильные данные будет продолжение выполнения и возврат заведомо безопасного значения. Численные расчеты могут возвращать 0. Операция со строкой может вернуть пустую строку, а операция с указателем — пустой указатель. Метод рисования в видеоигре, получивший неправильное исходное значение цвета, может по умолчанию использовать цвет фона или изображения. Однако в методе рисования рентгеновского снимка ракового больного вряд ли стоит применять «нейтральное значение». В таких случаях лучше прекратить выполнение программы, чем показать пациенту неправильные результаты.


с.191

Некоторые системы прекращают работу при возникновении любой ошибки. Этот подход оправдан в приложениях, критичных к безопасности. Например, какая реакция на ошибку будет наилучшей, если ПО, контролирующее радиационное оборудование для лечения рака, получит некорректное значение радиационной дозы? Надо ли использовать то же значение, что и в предыдущий раз? А может, ближайшее допустимое или нейтральное значение? В этом случае остановка работы — наилучший вариант. Мы охотнее предпочтем перезагрузить машину, чем рискнуть применить неправильную дозу.


с.192

Устойчивость против корректности
Как нам показали примеры с видеоигрой и рентгеновской установкой, выбор подходящего метода обработки ошибки зависит от приложения, в котором эта ошибка происходит. Кроме того, обработка ошибок в общем случае может стремиться либо к большей корректности, либо к большей устойчивости кода. Разработчики привыкли применять эти термины неформально, но, строго говоря, эти термины находятся на разных концах шкалы. Корректность предполагает, что нельзя возвращать неточный результат; лучше не вернуть ничего, чем неточное значение. Устойчивость требует всегда пытаться сделать что-то, что позволит программе продолжить работу, даже если это приведет к частично неверным результатам.
Приложения, требовательные к безопасности, часто предпочитают корректность устойчивости. Лучше не вернуть никакого результата, чем неправильный результат. Радиационная машина — хороший пример применения такого принципа.
В потребительских приложениях устойчивость, напротив, предпочтительнее корректности. Какой-то результат всегда лучше, чем прекращение работы. Текстовый редактор, которым я пользуюсь, временами показывает последнюю на экране строку лишь частично. Хочу ли я, чтобы при обнаружении этой ситуации редактор завершал выполнение? Нет: когда я в следующий раз нажму Page Up или Page Down, экран обновится, и изображение исправится.


Кстати, полнотекстный поиск в Яндексе нашёл ссылочку на эту книжку:
http://www.rworks.ru/rmanual/149/62/
Форматирование там потеряно, но прочитать избранные места вполне можно.
Re[6]: Проверка аргументов метода
От: _FRED_ Черногория
Дата: 25.08.09 05:30
Оценка:
Здравствуйте, andy1618, Вы писали:

A>Примеры не совсем точные, приводил по памяти. На всякий случай — вот точные цитаты

A>(Макконнелл С. "Совершенный код. Мастер-класс" / Пер. с англ. — М.: Издетальство "Русская Редакция", 2007.)

A>с.189

A>

Иногда наилучшей реакцией на неправильные данные будет продолжение выполнения и возврат заведомо безопасного значения.


По-моему, это называется "замазывание", "прикрытие" (если не сказать "сокрытие") ошибок. Определять, что нужно делать с неверными входными данными (если вообще что-то надо делать) нужно в точке вызова, а не в вызываемом коде.

A>с.191

A>

Некоторые системы прекращают работу при возникновении любой ошибки.


Примеры действительно "не в кассу" — например Вордина и Студия, не являясь жизненно необходимым софтом вылетают сразу (ИМХО, правильно).

[offtop]
Из последнего найденного — stack overflow в T4:
<#@ template language="C#" #>

<# Test(); #>
<#+ void Test() { Test(); } #>

[/offtop]

A>

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


Верно, но определять, как себя должна вести программа следует не в том месте, куда уже пришли неверные данные, а там, кто эти данные формирует.
Help will always be given at Hogwarts to those who ask for it.
Re[7]: Аналогия
От: _FRED_ Черногория
Дата: 25.08.09 05:37
Оценка:
Здравствуйте, bnk, Вы писали:

bnk>Кстати, такой вот пример. Возьмем например человека, который понял, что в его жизни что-то идет не так.

bnk>Ну например ему стукнул тридцатник, а у него ни кола ни двора ни определенной цели
bnk>Также два варианта:

bnk>- Убить себя об стену.

bnk>- Попытаться как-то выйти из этого положения.

bnk>Если бы это была отладочная версия, то первый вариант определенно выигрывает.

bnk>А так, второй вариант выглядит предпочтительнее.

bnk>


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

Целью же софта, на мой скромный взгляд, является _правильное_ осуществление своей работы, в соответствии с запрограмированной, описанной в задании, логикой. И поэтому при норушении данной логики (что-то мы запрограмировали не так, как было надо) продолжать работать бессмысленно, как становится бессмысленной жизнь человека, который с рждения готовил себя к одному, а потом потерял это. но человек — не машина, если ему повезёт, он может найти другую цель и начать стремиться к ней. У софта такого выбора нет :о)
Help will always be given at Hogwarts to those who ask for it.
Re[7]: Проверка аргументов метода
От: andy1618 Россия  
Дата: 25.08.09 05:50
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Примеры действительно "не в кассу" — например Вордина и Студия, не являясь жизненно необходимым софтом вылетают сразу (ИМХО, правильно).


Честно говоря, я тоже всегда был сторонником "fail fast", но приведённый уважаемым IT пример с аппаратом искусственного дыхания показывает, что иногда подход "уж лучше плохо, чем совсем никак" вполне оправдан. И, собственно, целью приведения ссылки на Макконнелла было подчеркнуть "холиварность" темы (что корректность и устойчивость обычно плохо совместимы, и единственно правильного рецепта на все случаи жизни не существует).
Re[8]: Проверка аргументов метода
От: _FRED_ Черногория
Дата: 25.08.09 06:02
Оценка: 1 (1)
Здравствуйте, andy1618, Вы писали:

_FR>>Примеры действительно "не в кассу" — например Вордина и Студия, не являясь жизненно необходимым софтом вылетают сразу (ИМХО, правильно).


A>Честно говоря, я тоже всегда был сторонником "fail fast", но приведённый уважаемым IT пример с аппаратом искусственного дыхания показывает,


Как-то я пропусти "пример IT с аппаратом искусственного дыхания" в этом топике где он?

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


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

А можно писать код безо всякий изощрений, но как следует продумав обработку ошибки на системном уровне, например, предусмотрев сервис, который следит за тем, работает ли программа, и при её вылете запускающим резерв и сообщающим всем заинтересованным лицам — админам, тех. персоналу, службе поддержки и т.п. о ЧП. Например, по СМС\пейджеру\мессенджеру.
Help will always be given at Hogwarts to those who ask for it.
Re[8]: Проверка аргументов метода
От: HowardLovekraft  
Дата: 25.08.09 06:39
Оценка:
Поддерживаю т.з. _FRED_'а.
Из своей практики — использование разного рода watchdog'ов предпочтительнее, чем работа с данными, чья целостность нарушена. Лучше упасть, с последующим перезапуском и откатом к предыдущей версии данных.
Re[9]: Проверка аргументов метода
От: andy1618 Россия  
Дата: 25.08.09 06:41
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Как-то я пропусти "пример IT с аппаратом искусственного дыхания" в этом топике где он?


Вот тут:
http://www.rsdn.ru/forum/dotnet/3514387.aspx
Автор: IT
Дата: 25.08.09



_FR>А можно писать код безо всякий изощрений, но как следует продумав обработку ошибки на системном уровне, например, предусмотрев сервис, который следит за тем, работает ли программа, и при её вылете запускающим резерв и сообщающим всем заинтересованным лицам — админам, тех. персоналу, службе поддержки и т.п. о ЧП. Например, по СМС\пейджеру\мессенджеру.


Да, есть и аппаратные решения — типа Watchdog timer. Эффективность, кстати, очень высокая!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.