Кодовые контракты на автоматически реализованные свойства

Есть ли способ поставить контракты на автоматически реализованные свойства в .NET? (И как ответ "Да" )?

(я предполагаю, что с помощью DevLabs заключают контракты .NET кода)

Ответы

Ответ 1

Спасибо Porges.

Моя ошибка заключалась в том, что я действительно использовал параметр ReleaseRequires, который действительно имеет дело только с generic версией метода Requires<T>.

Инвариант, который помещается в автоматически реализованное свойство, действительно превращается в предварительное условие Requires, но он не является общим - почему он не работает с использованием этой опции.

Что делать:

  • VARIANT 1. Рассмотрите возможность использования фрагментов кода и прекрасных Requires<T> вместо автоматически реализованных свойств, что позволяет нам использовать исключения желаемого типа.

  • VARIANT 2. Измените параметр ReleaseRequires на Preconditions в параметрах кода контракта и не стесняйтесь записывать инварианты в автоматические свойства - инструмент перезаписи автоматически изменит их в Requires. Тем не менее, они будут неэквивалентными - это означает, что в случае нарушения контракта будет отклонен ContractException, и нет никакого способа изменить это поведение.

Спасибо всем за помощь!

Ответ 2

Да, это возможно - все, что необходимо, - это добавить условие контракта к методу [ContractInvariantMethod] в вашем классе, которое затем добавляет эквивалентное условие Requires к автоматическому set ter, и условие сообщения Ensures добавляется к get. Из раздела 2.3.1 Ссылка

Как показывает пример, инварианты на авто-свойствах превращаются в:

  • Предварительное условие для установщика
  • Постусловие для геттера
  • Инвариант для базового поля поддержки

И на примере:

public int MyProperty { get; private set ;}

[ContractInvariantMethod]
private void ObjectInvariant ()
{
  Contract.Invariant ( this.MyProperty >= 0 );
}

"эквивалентен следующему коду:"

private int backingFieldForMyProperty;
public int MyProperty 
{
  get 
  {
    Contract.Ensures(Contract.Result<int>() >= 0);
    return this.backingFieldForMyProperty;
  }

  private set 
  {
    Contract.Requires(value >= 0);
    this.backingFieldForMyProperty = value;
  }
}

[ContractInvariantMethod]
private void ObjectInvariant () 
{
  Contract.Invariant ( this.backingFieldForMyProperty >= 0 );
...

Ответ 3

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