Объединение кодовых контрактов и регулярных выражений - PullRequest
2 голосов
/ 10 марта 2011

Итак, у меня есть очень простой класс с одной строкой в ​​качестве свойства. Эта строка должна иметь определенный шаблон. Я пытаюсь реализовать это с помощью контрактов кода. Класс выглядит примерно так:

class SimpleClass
{
    public Property { get; set; }

    public SimpleClass(string prop)
    {
      Contract.Requires(IsValid(prop));
      this.Property = prop;
    }

    [ContractInvariantMethod]
    void ObjectInvariant()
    {
      Contract.Invariant(IsValid(Property));
    }

    bool IsValid(string arg)
    {
      // Use regex to check if arg is a valid string
    }
}

Очень просто. Однако это вызывает нечитаемое исключение, а другое говорит, что «Member SimpleClass.IsValid имеет меньшую видимость, чем включающий метод SimpleClass. # Ctor (System.String)». Почему это незаконно? Должен ли я скопировать / вставить регулярное выражение в оба метода? Это, кажется, противоположность права. Пожалуйста, помогите мне понять!

Ответы [ 3 ]

5 голосов
/ 10 марта 2011

Другой способ - избежать «примитивной одержимости» и использовать класс, приспособленный к вашей цели, например:

public SimpleClass(Email address)
{
    // no need to check, it must be valid :)
}

..., а затем инкапсулировать всю логику проверки в классе Email.У вас по-прежнему будут проблемы с «строковым форматом», связанные с проверкой, но я думаю, что лучшая идиома для этого - создать метод с именем Email.TryParse и оформить его в соответствии с int.TryParse.

5 голосов
/ 10 марта 2011

Просто отметьте IsValid как public, и все будет в порядке.Все «компоненты» публичного наземного контракта также должны быть публичными, в противном случае вызывающий абонент не сможет проверить, что контракт выполнен.

@ AI-CII Я понимаю, ноэто также было бы недостатком дизайна, раскрывая детали реализации потребителям.

  1. Контракт на публичный метод не является деталью реализации.A Contract.Requires говорит: «Эй, я требую, чтобы это было правдой, чтобы я сделал для тебя какую-то работу».Если «это» не видно вызывающей стороне, как вызывающая сторона может проверить, что контракт выполнен?

  2. Вы не раскрываете подробности реализации метода IsValid,вы показываете только то, что должно быть удовлетворено, чтобы вызываемый выполнял свою работу.

1 голос
/ 10 марта 2011

Как уже говорил Джейсон, Code Contracts требует, чтобы метод был общедоступным, поскольку вы уже сами выяснили это благодаря сообщению об исключении.

Я понимаю, однако, что просто сделать его публичным не кажется правильным.Возможно, условие регулярного выражения может быть инкапсулировано в статическую глобальную функцию вспомогательного класса?

Например, если нужно проверить, является ли строка допустимым URL-адресом.

UrlHelper.IsValidUrl( string url )

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

Он называется Сокращения кода контракта .Однако вы должны сами включить исходный файл в свой проект.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...