为什么Code Contracts建议我要求参数为null?

时间:2015-09-29 18:39:48

标签: c# code-contracts

查看下面的代码示例,Microsoft Code Contracts警告:

  

CodeContracts:在极其可见的方法中缺少前置条件。   考虑添加Contract.Requires(science == null);用于参数   验证

我在这里遗漏了什么吗?为什么CC会建议我要求参数为null,这与此处应该做的完全相反?

我正在使用VS2015,.NET 4.6。

using System;
using System.Diagnostics.Contracts;
public sealed class Weird
{

    public Weird(object science)
    {
        if (null == science)
        {
            throw new ArgumentNullException();
        }

        Contract.EndContractBlock();

        this.Science = science;
    }
    private object Science { get; }

    [ContractInvariantMethod]
    private void ObjectInvariant()
    {
        Contract.Invariant(null != this.Science);
    }
}

4 个答案:

答案 0 :(得分:4)

这不是一个比你的解决方案更好的答案,但我得到了#34; work"只需改变:

private object Science { get; }

为:

private object Science { get; set; }

基本上与您的解决方法相同,但没有提供您自己的支持字段。我猜Code Code不太了解新语法。

答案 1 :(得分:3)

尽量不要使用反向比较。在C#中,没有必要写:

if (null == science)

而不是

if (science == null)

您的代码将变得更加清晰,我认为错误的合同建议将会消失。

此外,如果您在=块内发生错误并只编写一个赋值(if),编译器会向您发出警告。

为了使您的代码更加清晰,您可以尝试使用一些AOP内容,例如PostSharp,并将您的契约指定为接口中的属性属性,您的类将实现这些属性。所以契约逻辑不会与业务逻辑交错。

答案 2 :(得分:2)

基于解决方法,CC看起来并不了解只读的auto属性在构造函数中是可写的。这两种解决方法都提供了删除写入只读属性的操作。也许CC试图通过将执行发送到唯一的其他可用分支(this.Science = science;)来避免执行它认为错误的语句(null == science)。

早期版本的C#不允许写入只读的自动属性。我猜Code Codects系统没有收到备忘录!

答案 3 :(得分:1)

当我用一个字段支持的属性替换auto属性时,我发现警告消失了。将以下代码与我在原始问题中发布的内容进行比较:

using System;
using System.Diagnostics.Contracts;
public sealed class Weird
{        
    public Weird(object science)
    {
        if (science == null)
        {
            throw new ArgumentNullException();
        }

        Contract.EndContractBlock();

        this.science = science;
    }

    private readonly object science;

    private object Science
    {
        get
        {
            return this.science;
        }
    }

    [ContractInvariantMethod]
    private void ObjectInvariant()
    {
        Contract.Invariant(null != this.Science);
    }
}

我不喜欢这个,因为我不一定只是为了满足代码合同而使用现场支持的财产。但是,噢,我猜。

我仍然愿意接受一个允许我在使用自动属性时满足合同的答案。