c# - 代码契约(Contract)静态检查器 : Possibly calling a method on a null reference — why?

标签 c# .net code-contracts

我有以下类(class):

public class AndSpecification<TEntity> : ISpecification<TEntity>
{
    protected ISpecification<TEntity> First { get; private set; }
    protected ISpecification<TEntity> Second { get; private set; }

    public bool IsSatisfiedBy(TEntity entity)
    {
        return First.IsSatisfiedBy(entity) && Second.IsSatisfiedBy(entity);
    }

    public AndSpecification(ISpecification<TEntity> first, ISpecification<TEntity> second)
    {
        Contract.Requires(first != null);
        Contract.Requires(second != null);
        Contract.Ensures(First != null);
        Contract.Ensures(Second != null);

        First = first;
        Second = second;
    }
}

请注意,我使用 Contract.Ensures()确保调用构造函数后,FirstSecond永远不会为空。然而,Code Contracts 在 IsSatisfiedBy() 中给我一个警告方法实现:CodeContracts: Possibly calling a method on a null reference 'this.First' (与 Second 相同)。无法弄清楚出了什么问题,是我还是静态检查器?

最佳答案

您似乎缺少一些契约和对象不变量。我把你的代码放在上面并对它运行代码契约(Contract)静态分析,并得到了你所得到的。然后,我按照自己的方式完成代码,以获得满足静态分析器要求的实现。

[ContractClass(typeof(ISpecificationContracts<>))]
public interface ISpecification<TEntity> 
    where TEntity : class
{
    bool IsSatisfiedBy(TEntity entity);
}

[ContractClassFor(typeof(ISpecification<>))]
abstract class ISpecificationContracts<TEntity> 
    : ISpecification<TEntity> where TEntity : class
{
    public bool IsSatisfiedBy(TEntity entity)
    {
        Contract.Requires(entity != null);
        throw new NotImplementedException();
    }
}

public class AndSpecification<TEntity> 
    : ISpecification<TEntity> where TEntity : class
{
    private readonly ISpecification<TEntity> _first;
    private readonly ISpecification<TEntity> _second;

    protected ISpecification<TEntity> First {
        get
        {
            Contract.Ensures(Contract.Result<ISpecification<TEntity>>() != null);
            return _first;
        }
    }
    protected ISpecification<TEntity> Second
    {
        get
        {
            Contract.Ensures(Contract.Result<ISpecification<TEntity>>() != null);
            return _second;
        }
    }

    public bool IsSatisfiedBy(TEntity entity)
    {
        return First.IsSatisfiedBy(entity) && Second.IsSatisfiedBy(entity);
    }

    public AndSpecification(ISpecification<TEntity> first,
                            ISpecification<TEntity> second)
    {
        Contract.Requires(first != null);
        Contract.Requires(second != null);
        Contract.Ensures(_first == first);
        Contract.Ensures(_second == second);

        _first = first;
        _second = second;
    }

    [ContractInvariantMethod]
    [System.Diagnostics.CodeAnalysis.SuppressMessage(
        "Microsoft.Performance", 
        "CA1822:MarkMembersAsStatic", 
        Justification = "Required for code contracts.")]
    private void ObjectInvariant()
    {
        Contract.Invariant(_first != null);
        Contract.Invariant(_second != null);
    }

}

关于c# - 代码契约(Contract)静态检查器 : Possibly calling a method on a null reference — why?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26160866/

相关文章:

c# - 如何在 foreach 中隐式转换自定义 IEnumerable?

c# - C#Nest&Elasticsearch 6.x:如何过滤/计数嵌套字段(在内部List <object>中)

c# - 在wpf中获取文本框名称

c# - Code Contracts 是否未能发现 Nullable<T>.HasValue 和 null 之间的明显关系?

c# - DateTime 到 javascript 日期

.net - 用 mkbundle2 打包后,目标机器提示 libmono.so。为什么?

.net - 找不到任何 Caliburn Micro with Prism 的 sample

C# WPF - 应用程序图标 + ShowInTaskbar = False

c# - 为什么 Code Contracts 在带有 params keywork 的方法中显示 "Malformed contract. Found Requires after assignment"?

c# - C#代码契约(Contract): What can be statically proven and what can't?