Хороший способ проверки параметров? - PullRequest
8 голосов
/ 03 августа 2010

Мы используем среду .NET 2.0 с C # 3.0 (я думаю, что это последняя версия C #, которая может работать на версии 2.0 платформы, исправьте меня, если я ошибаюсь).

Есть ли что-то встроенное в C #, которое может сделать этот тип проверки параметров более удобным?

public ConnectionSettings(string url, string username, string password,
                          bool checkPermissions)
{
    if (username == null) {
        throw new ArgumentNullException("username");
    }

    if (password == null) {
        throw new ArgumentNullException("password");
    }

    if (String.IsNullOrEmpty(url)) {
        throw new ArgumentException("Must not be null or empty, it was " +
            (url == null ? url : "empty"), "url");
    }

    this.url = url;
    this.username = username;
    this.password = password;
    this.checkPermissions = checkPermissions;
}

Такой тип проверки параметров становится общим шаблоном и приводит к появлению большого количества «почти стандартного» кода в наших открытых методах.

Если ничего не встроено. Есть ли какие-нибудь отличные бесплатные библиотеки, которые мы могли бы использовать?

Ответы [ 8 ]

4 голосов
/ 03 августа 2010

Вы можете использовать il weaver, например Post Sharp , имейте в виду, что компилятор как сервис в C # 5 сделает такие вещи встроенными.

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

EG:

public ConnectionSettings(
   [NotNullOrEmpty] string url, 
   [NotNull] string username, 
   [NotNull] string password,
   bool checkPermissions)
{
    this.url = url;
    this.username = username;
    this.password = password;
    this.checkPermissions = checkPermissions;
}

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

4 голосов
/ 03 августа 2010

Обычно я создаю статические вспомогательные методы ...

Например:

public static void CheckNotNull(object value, string parameterName)
{
   if(value == null) { throw new ArgumentNullException(parameterName); }
}

Означает, что вы можете сжать ваш код до чего-то похожего на приведенное ниже и просто сделать его немного более аккуратным.

CheckNotNull(username, "username");
CheckNotNull(password, "password"); 

Или вы можете обернуть его как метод расширения:

public static void CheckNotNull<T>(this T value, string parameterName)
{
   if(value == null) { throw new ArgumentNullException(parameterName); }
}

И использовать как:

username.CheckNotNull("username");
password.CheckNotNull("password");

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

3 голосов
/ 03 августа 2010

Вот хороший беглый способ сделать это.

Какие ваши любимые методы расширения для C #?(codeplex.com/extensionoverflow)

public static class Extensions
{
        public static void ThrowIfArgumentIsNull<T>(this T obj, string parameterName) where T : class
        {
                if (obj == null) throw new ArgumentNullException(parameterName + " not allowed to be null");
        }
}

internal class Test
{
        public Test(string input1)
        {
                input1.ThrowIfArgumentIsNull("input1");
        }
}
2 голосов
/ 03 августа 2010

Идея аналогична быстрой проверке параметров, упомянутой Giorgi, но при этом исключается избыточное именование параметров и строк, которые не могут автоматически обновляться инструментами рефакторинга кода.

2 голосов
/ 03 августа 2010

Он не встроен в .Net Framework, но вы можете использовать Свободная проверка аргументов

2 голосов
/ 03 августа 2010

Вы можете сделать это, используя контракты, но это та же самая концепция.

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

1 голос
/ 03 августа 2010

Просто чтобы добавить ответ Сэма выше, вот ссылка, которая расскажет вам, как можно реализовать такие атрибуты с помощью PostSharp:

http://dpatrickcaldwell.blogspot.com/2009/03/validate-parameters-using-attributes.html

0 голосов
/ 31 июля 2018

Я недавно выпустил первую стабильную версию Guard , библиотеки, которая помогает вам писать защитные предложения, подобные этим:

public ConnectionSettings(
    Uri url, string username, string password, bool checkPermissions)
{
    this.username = Guard.Argument(() => username).NotNull();
    this.password = Guard.Argument(() => password).NotNull();
    this.url = Guard.Argument(() => url).NotNull().Https();
    this.checkPermissions = checkPermissions;
}
  • Это быстрее, чем вы думаете, этот документ углубляется в соображения производительности.
  • Вы можете добавить новые проверки в виде методов расширения, этот документ объясняет это подробно.
...