问题
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.
回答1:
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. :)
来源:https://stackoverflow.com/questions/3461972/am-i-implementing-this-simple-contract-incorrectly