Я неправильно выполняю этот простой контракт? - PullRequest
17 голосов
/ 11 августа 2010

Это мой код:

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 с 2 или менее сторонами.Мой (упрощенный) тест 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 пока нет подсветки совместимости для контрактов кода.

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

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

Спасибо.

1 Ответ

18 голосов
/ 11 августа 2010

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

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

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

polygon.VertexCount = 0;

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

...