Question

This is my code:

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);
    }

}

I have tried with both the Contract.Requires and Contract.Invariant methods to prevent the vertexCount variable from becoming less than or equal to 2; however I am still able to initialise a RegularPolygon with 2 or fewer sides. My (simplified) NUnit test looks like this:

[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));
    }

}

The above test also passes and I cannot figure out why!

At first I thought ReSharper might have been messing something up because it greys out the line and displays this message whenever I try to use a method in the Contract namespace:

Method invocation is skipped. Compiler will not generate method invocation because the method is conditional, or it is partial method without implementation.

But suspending R# and running the tests in NUnit has the same result with no errors or warnings in VS either. So I assume that is just because ReSharper does not have highlighting compatibility for code contracts yet.

I have looked at the documentation and as far as I can tell I shouldn't be having this problem.

Am I using code contracts incorrectly or is my environment preventing it from working somehow?

Thank you.

Was it helpful?

Solution

First thing to check - have you actually got contract checking turned on? If not, none of your contracts will do anything. That would explain the R# warning, too. Look under "Code Contracts" in the build properties, and see what it says under "Runtime Checking".

As per comments, ensure you have CONTRACTS_FULL defined as a compilation symbol - that appears to be what R# requires.

Second point: you've got public mutable fields, which means your invariant can be violated at any moment by someone writing

polygon.VertexCount = 0;

Please don't use public fields, particularly not writable ones. :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top