Более быстрый способ проверки аргументов метода

Это в основном просто из любопытства, и, возможно, это глупый вопрос. :)

У меня есть такой метод:

public void MyMethod(string arg1, string arg2, int arg3, string arg4, MyClass arg5)
{
    // some magic here
}

Ни один из аргументов не может быть нулевым, и ни один из строковых аргументов не может равняться String.Empty.

Вместо того, чтобы иметь большой список:

if(arg1 == string.Empty || arg1 == null)
{
    throw new ArgumentException("issue with arg1");
}

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

Прошу прощения, если мой вопрос не ясен.

Спасибо!


person AndrewC    schedule 13.04.2010    source источник
comment
Я немного посмотрел и опубликую это как комментарий, так как на самом деле это не ответ. В моей книге было бы замечательно, если бы мы могли определить символ, который будет использоваться для аргументов в сигнатуре метода. Итак, допустим, мы назначаем проверки ненулевого и непустого для символа!, А затем в сигнатуре метода это может быть MyMethod (string! MyArg), при этом C # выполняет автоматическую проверку и генерирует исключения. Конечно, сейчас я могу сделать это с помощью метода, но если бы я мог назначить символ, который я мог бы использовать в подписи, набрать его было бы намного быстрее! Мысли?   -  person AndrewC    schedule 13.04.2010


Ответы (7)


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

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

person Andrew Bezzub    schedule 13.04.2010

Вы можете использовать String.IsNullOrEmpty:

if (String.IsNullOrEmpty(arg1) )
    throw new ArgumentException("issue with arg1");

Если вы используете Framework 4, есть также String.IsNullOrWhiteSpace (возможно, вы также захотите выбросить, если кто-то вызывает метод со строкой, содержащей только пробелы).

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

В рамках 4 у вас также есть Код Contracts, но синтаксис для его использования остается вызовом метода.

person driis    schedule 13.04.2010
comment
Это круто, хотя мне интересно, есть ли еще более быстрый способ. Подумайте вслух, но было бы здорово, если бы существовала некоторая форма сокращенной записи, которая могла бы быть добавлена ​​к аргументам в сигнатуре метода, чтобы C # автоматически генерировал исключение аргумента, если оно было нулевым или пустым. - person AndrewC; 13.04.2010

if (string.IsNullOrEmpty(arg1))
{
    throw new ArgumentException("issue with arg1");
}

Также в .NET 4 есть кодовые контракты.

person Darin Dimitrov    schedule 13.04.2010

Есть хорошая библиотека под названием CuttingEdge.Conditions, которая предоставляет удобный интерфейс для этого:

public void MyMethod(string arg1, string arg2, int arg3, string arg4, MyClass arg5)
{
    Condition.Requires(arg1, "arg1").IsNotNull().IsNotEmpty().StartsWith("Foo");
}

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

person Reed Copsey    schedule 13.04.2010
comment
К сожалению, он больше не поддерживается. Я рекомендую Guard людям, которые ищут альтернативу. (Отказ от ответственности: я автор) - person Şafak Gür; 31.07.2018

Настоящая проблема здесь в том, что у вашего метода слишком много аргументов. Это затрудняет написание кода проверки. Делает его громоздким и для клиентского кода. Подумайте о написании вспомогательного класса, в котором аргументы, которые вы теперь передаете, являются свойствами. Теперь ваш метод может принимать только один аргумент. И проверка может выполняться в самом классе, а не в вашем методе.

Каноническим примером этого шаблона в Framework является класс Process. Вспомогательный класс ProcessStartInfo сохраняет его работоспособность.

person Hans Passant    schedule 13.04.2010

Во-первых, вы можете использовать if (!String.IsNullOrEmpty(arg1)), чтобы уменьшить выражение if.

Во-вторых, нужна ли вам проверка аргументов в сборке выпуска или достаточно выполнить проверку аргументов в сборке отладки? Это зависит от того, откуда поступают данные. Если эта функция вызывается вашим собственным кодом, а аргументы обрабатываются вызывающим кодом, вероятно, будет достаточно проверить аргументы только в ваших отладочных сборках. В этом случае используйте Debug.Assert(!String.IsNullOrEmpty(arg1), "msg"); и т. Д. Утверждения удаляются из сборок выпуска.

В-третьих, ознакомьтесь с DevLabs: Code Contracts

person dthorpe    schedule 13.04.2010

Насколько я могу понять ваш вопрос, как насчет этого:

static void Main(string[] args)
{
    Test(null, "", "", "");
}

static void Test(MyClass arg1, params string[] args)
{
    if (args.Count(a => String.IsNullOrEmpty(a)) == args.Length)
    {
        throw new Exception("All params are null or empty");
    }
}
person abatishchev    schedule 13.04.2010
comment
Вы имеете в виду if (args.Any(a => a == null || (a is string && !string.IsNullOrEmpty(a))){throw new Exception("No param can be null or empty.")}? - person ANeves thinks SE is evil; 13.04.2010
comment
@sr pt: Спасибо! Отличный отзыв о Any() - person abatishchev; 13.04.2010