Можно ли указать кодовые контракты, чтобы гарантировать, что метод не меняет состояние объекта - PullRequest
6 голосов
/ 04 декабря 2011

Допустим, я получил логическое свойство IsValid для моего объекта.

Я хотел бы создать метод и убедиться, что IsValid не изменился после его вызова, независимо от того, было ли это true или false перед вызовом.

Есть ли поддержка такой вещи?

Ответы [ 4 ]

5 голосов
/ 04 декабря 2011

Для этой цели атрибут [Pure] был добавлен в пространство имен System.Diagnostic.Contracts .См. здесь для дальнейшего объяснения.Однако вы не можете предотвратить изменение одного свойства.Метод не может изменять состояние объекта вообще (например, C ++ const).

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

public class Test
{
    private int x = 0;

    [Pure]
    public void Foo()
    {
        x++;
    }
}

Что касается документации проверки * Pure будут поддерживаться «в будущем»».Когда бы это ни было («Команда Code Contracts усердно работает над этим, чтобы в будущем выпустить проверку чистоты».).

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

Поэтому ответ на ваш вопрос таков: в настоящее время это не поддерживается, но может быть в будущем.

3 голосов
/ 05 декабря 2011

Я сам не пробовал, но в соответствии с MSDN Contract.OldValue может помочь проверить, что значение одного свойства не изменилось:

public bool IsValid
{
  get
  {
    ...
  }
}

public void SomeMethod()
{
  Contract.Ensures(this.IsValid == Contract.OldValue(this.IsValid));
  ...
}
1 голос
/ 04 декабря 2011

Единственный способ сделать это - контролировать свой код таким образом, чтобы вы знали, что он не изменится.Нет никакого специального кода или синтаксиса, чтобы управлять этим иначе (как в C ++).

1 голос
/ 04 декабря 2011

Нет, к сожалению, в c # нет такой логики, как в c ++.

...