Contract.Requires 未阻止空引用警告(紫色波浪形)

Contract.Requires not preventing a null reference warning (purple squiggly)

我在构造函数中指定参数不为空。这些字段是私有的,没有其他代码可用于静态检查以怀疑这些字段是否设置为空。

尽管如此,我收到来自 Visual Studio 2013 的警告,它们可能为空。

CodeContracts: Possibly accessing a field on a null reference 'this.origin'

它们怎么可能为空?也许静态检查器无法解决这个问题?还是我做的不对?

using System.Diagnostics.Contracts;

public class Link
{

    private Shape origin;
    private Shape destination;

    public Link(Shape origin, Shape destination)
    {
        Contract.Requires(origin != null);
        Contract.Requires(destination != null);
        this.origin = origin;
        this.destination = destination;
    }

    public string OriginID()
    {
        return origin.ID; // getting purple squiggly here
    }

    public string DestinationID()
    {
        return destination.ID; // getting purple squiggly here
    }

}

编辑:

他们现在走了。不过我的问题仍然存在,因为我不知道我做了什么让它们消失。我没有更改此 class 中的任何内容,也没有更改项目设置。只是,在我收到警告时,我的一项测试没有通过,现在所有测试都通过了。那是当时和现在的唯一区别。使测试通过的更改在另一个 class 中,而不是这个。

根据您的项目设置,我不相信静态检查器总是能够计算出 origindestination 上的不变量。

可以采取多种方法来解决此警告:

ContractInvariantMethod

添加带有 ContractInvariantMethodAttribute 属性的显式私有方法并调用 Contract.Invariant,例如:

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

这将通知静态检查器永远不会违反这些不变量,即 origindestination 永远不会为空。

只读 + 为只读推断不变量

将这两个字段标记为只读,并在您的代码合同设置中,确保为静态检查器选中 Infer invariants for readonly 选项:

我个人倾向于使用 ContractInvariantMethod 方法,但如果它们仅在实例化时初始化,我也会将我的字段标记为 readonly,但是这两种方法都应该有效。