Подтвердить что ты не робот

Я выполняю этот простой контракт неправильно?

Это мой код:

public class RegularPolygon
{
    public int VertexCount;
    public double SideLength;

    public RegularPolygon(int vertexCount, double sideLength)
    {
        Contract.Requires(vertexCount >= 3);
        VertexCount = vertexCount;
        SideLength = sideLength;
    }

    [ContractInvariantMethod]
    private void RegularPolygonInvariants()
    {
        Contract.Invariant(VertexCount>=3);
    }

}

Я попытался использовать методы Contract.Requires и Contract.Invariant, чтобы исключить, что переменная vertexCount становится меньше или равна 2; однако я все еще могу инициализировать RegularPolygon с двумя или меньшими сторонами. Мой (упрощенный) тест NUnit выглядит следующим образом:

[TestFixture]
class TestRegularPolygon
{
    private RegularPolygon _polygon;

    [SetUp]
    public void Init()
    {
        _polygon = new RegularPolygon(1, 50);
    }

    [Test]
    public void Constructor()
    {
        Assert.That(_polygon.VertexCount,Is.GreaterThanOrEqualTo(3));
    }

}

Вышеупомянутый тест также проходит, и я не могу понять, почему!

Сначала я думал, что ReSharper мог бы что-то испортить, потому что он вычеркивает строку и отображает это сообщение всякий раз, когда я пытаюсь использовать метод в пространстве имен Contract:

Вызов метода пропущен. Компилятор не будет генерировать вызов метода, потому что метод является условным, или это частичный метод без реализации.

Но приостановка R # и запуск тестов в NUnit имеет тот же результат без ошибок или предупреждений в VS. Поэтому я предполагаю, что это только потому, что ReSharper еще не выделяет совместимость для кодовых контрактов.

Я просмотрел документацию, и насколько я могу судить, у меня не должно быть этой проблемы.

Я неправильно использую кодовые контракты или моя среда не позволяет ему работать каким-то образом?

Спасибо.

4b9b3361

Ответ 1

Первое, что нужно проверить - действительно ли вы включили проверку контракта? Если нет, ни один из ваших контрактов ничего не сделает. Это также объясняет предупреждение R #. Посмотрите в разделе "Кодовые контракты" в свойствах сборки и посмотрите, что он говорит в разделе "Проверка времени выполнения".

В соответствии с комментариями убедитесь, что у вас есть CONTRACTS_FULL, определенный как символ компиляции, - это похоже на то, что требуется R #.

Вторая точка: у вас есть общедоступные изменяемые поля, что означает, что ваш инвариант может быть нарушен в любой момент кем-то, пишущим

polygon.VertexCount = 0;

Пожалуйста, не используйте общедоступные поля, особенно не записываемые.:)