17

这是我的代码:

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.RequiresContract.Invariant方法来防止 vertexCount 变量小于或等于 2;但是我仍然可以初始化具有 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 还没有突出代码合同的兼容性。

我查看了文档,据我所知,我不应该遇到这个问题。

我是在错误地使用代码合同,还是我的环境阻止了它以某种方式工作?

谢谢你。

4

1 回答 1

19

首先要检查 - 你真的打开了合同检查吗?如果没有,您的任何合同都不会做任何事情。这也可以解释 R# 警告。查看构建属性中的“代码合同”,并查看“运行时检查”下的内容。

根据评论,确保您已CONTRACTS_FULL定义为编译符号 - 这似乎是 R# 所要求的。

第二点:你有公共的可变字段,这意味着你的不变量随时可能被某人写违反

polygon.VertexCount = 0;

请不要使用公共领域,尤其是不可写的领域。:)

于 2010-08-11T19:20:17.967 回答