Каков самый гладкий, самый привлекательный синтаксис, который Вы нашли для утверждения правильности параметра в c#?

Спасибо Цываресу за помощь!

set ( OpenCV_DIR   "/home/xxxxx/opencv-3.0.0/build/")

до

find_package( OpenCV 3.0 REQUIRED)

в cmakelists.txt

Спасибо!

29
задан Jon Skeet 21 March 2009 в 21:58
поделиться

14 ответов

Это может быть несколько полезно:

Дизайн contract/C# 4.0/avoiding ArgumentNullException

6
ответ дан Community 14 October 2019 в 08:00
поделиться

Это не применяется везде, но это могло бы помочь во многих случаях:

я предполагаю, что "SomeMethod" проводит некоторую поведенческую операцию на данных "фамилия", "имя" и "возраст". Оцените свой текущий дизайн кода. Если три части данных кричат для класса, поместите их в класс. В том классе можно также поместить проверки. Это освободило бы "SomeMethod" от входной проверки.

конечный результат был бы чем-то вроде этого:

public void SomeMethod(Person person)
{
    person.CheckInvariants();
    // code here ...
}

вызов был бы чем-то вроде этого (при использовании.NET 3.5):

SomeMethod(new Person { FirstName = "Joe", LastName = "White", Age = 12 });

под предположением, что класс был бы похож на это:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }

    public void CheckInvariants()
    {
        assertNotNull(FirstName, "first name");
        assertNotNull(LastName, "last name");
    }

    // here are your checks ...
    private void assertNotNull(string input, string hint)
    {
        if (input == null)
        {
            string message = string.Format("The given {0} is null.", hint);
            throw new ApplicationException(message);
        }
    }

Вместо синтаксического сахара.NET 3.5 можно также использовать аргументы конструктора для создания объекта Человека.

0
ответ дан Theo Lenndorff 14 October 2019 в 08:00
поделиться

Так же, как контраст этот сообщение MiЕЎko Hevery на Google Testing Blog утверждает, что этот вид проверки параметра не мог бы всегда быть хорошей вещью. Получающиеся дебаты в комментариях также поднимают некоторые интересные вопросы.

0
ответ дан Henrik Gustafsson 14 October 2019 в 08:00
поделиться

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

Среди тех.. Система. ArgumentException, Система. ArgumentNullException...

0
ответ дан markt 14 October 2019 в 08:00
поделиться

Мое предпочтение состояло бы в том, чтобы просто оценить условие и передать результат вместо того, чтобы передать выражение, которое будет оценено и параметр, на котором можно оценить его. Кроме того, я предпочитаю иметь способность настроить все сообщение. Обратите внимание, что это просто предпочтения - я не говорю, что Ваш образец является неправильным - но существуют некоторые случаи, где это очень полезно.

Helper.Validate( firstName != null || !string.IsNullOrEmpty(directoryID),
                 "The value for firstName cannot be null if a directory ID is not supplied." );
1
ответ дан tvanfosson 14 October 2019 в 08:00
поделиться

Пострезкий или некоторый другой платформа AOP .

0
ответ дан Kris Erickson 14 October 2019 в 08:00
поделиться

Не знайте, передает ли эта техника от C/C++ до C#, но я сделал это с макросами:


    #define CHECK_NULL(x)  { (x) != NULL || \
           fprintf(stderr, "The value of %s in %s, line %d is null.\n", \
           #x, __FILENAME__, __LINE__); }
 
0
ответ дан Adam Liss 14 October 2019 в 08:00
поделиться

Пользование моей библиотекой Троица Помощника :

public void SomeMethod(string firstName, string lastName, int age)
{
    firstName.AssertNotNull("firstName");
    lastName.AssertNotNull("lastName");

    ...
}

Также поддержки, утверждающие, что параметры перечисления корректны, наборы и их содержание не - null, строковые параметры непусты и так далее. См. пользовательскую документацию здесь для подробных примеров.

5
ответ дан Tim Cooper 14 October 2019 в 08:00
поделиться

В порядке парни, это - я снова, и я нашел что-то еще, что удивительно и восхитительно. Это - еще одно сообщение в блоге, упомянутое от другого ТАК вопрос, который упомянул Chris, выше.

подход Этого парня позволяет Вам записать это:

public class WebServer
    {
        public void BootstrapServer( int port, string rootDirectory, string serverName )
        {
            Guard.IsNotNull( () => rootDirectory );
            Guard.IsNotNull( () => serverName );

            // Bootstrap the server
        }
    }

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

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

И реализация довольно просто, следующим образом:

public static class Guard
    {
        public static void IsNotNull<T>(Expression<Func<T>> expr)
        {
            // expression value != default of T
            if (!expr.Compile()().Equals(default(T)))
                return;

            var param = (MemberExpression) expr.Body;
            throw new ArgumentNullException(param.Member.Name);
        }
    }

Примечание, что это использует "статическое отражение", таким образом, в жестком цикле или чем-то, Вы могли бы хотеть использовать подход Rick Brewster выше.

, Как только я отправляю это, я собираюсь голосовать за Chris и ответ на другой ТАК вопрос. Это - некоторый хороший материал!!!

6
ответ дан Charlie Flowers 14 October 2019 в 08:00
поделиться

Ничего себе, я нашел что-то действительно интересным здесь. Chris выше дал ссылку на другой вопрос о Переполнении стека. Один из ответов там указал на сообщение в блоге, которое описывает, как получить код как это:

public static void Copy<T>(T[] dst, long dstOffset, T[] src, long srcOffset, long length)
{
    Validate.Begin()
            .IsNotNull(dst, “dst”)
            .IsNotNull(src, “src”)
            .Check()
            .IsPositive(length)
            .IsIndexInRange(dst, dstOffset, “dstOffset”)
            .IsIndexInRange(dst, dstOffset + length, “dstOffset + length”)
            .IsIndexInRange(src, srcOffset, “srcOffset”)
            .IsIndexInRange(src, srcOffset + length, “srcOffset + length”)
            .Check();

    for (int di = dstOffset; di < dstOffset + length; ++di)
        dst[di] = src[di - dstOffset + srcOffset];
}

я не убежден, что это лучший ответ все же, но это, конечно, интересно. Вот сообщение в блоге от Rick Brewster.

11
ответ дан Charlie Flowers 14 October 2019 в 08:00
поделиться

Необходимо проверить Контракты Кода ; они делают в значительной степени точно, что Вы спрашиваете. Пример:

[Pure]
public static double GetDistance(Point p1, Point p2)
{
    CodeContract.RequiresAlways(p1 != null);
    CodeContract.RequiresAlways(p2 != null); 
    // ...
}
15
ответ дан John Feminella 14 October 2019 в 08:00
поделиться

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

Вот мое решение .

Краткий обзор - учитывая этот бит кода:

int x = 3;
string t = "hi";
Assert(() => 5*x + (2 / t.Length) < 99);

Мой Утверждать функцию может распечатать следующую сводку того, что передается ей:

(((5 * x) + (2 / t.Length)) < 99) == True where
{
  ((5 * x) + (2 / t.Length)) == 16 where
  {
    (5 * x) == 15 where
    {
      x == 3
    }
    (2 / t.Length) == 1 where
    {
      t.Length == 2 where
      {
        t == "hi"
      }
    }
  }
}

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

7
ответ дан Daniel Earwicker 14 October 2019 в 08:00
поделиться

Общие библиотеки Lokad также имеют реализацию, основанную на синтаксическом анализе IL, что позволяет избежать дублирования имени параметра в строке.

Например:

Enforce.Arguments(() => controller, () => viewManager,() => workspace);

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

например,

Enforce.Argument(() => username,    StringIs.Limited(3, 64), StringIs.ValidEmail);
2
ответ дан 28 November 2019 в 01:26
поделиться

Вот мой ответ на проблему. Я называю это « Когти стража ». Он использует анализатор IL из Lokad Shared Libs, но имеет более простой подход к формулированию фактических защитных предложений:

string test = null;
Claws.NotNull(() => test);

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

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

Ссылки не работают, здесь это URL: http://github.com/littlebits/guard_claws/

4
ответ дан 28 November 2019 в 01:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: