c# - 在 Func<> 上定义代码契约

标签 c# code-contracts

我正在尝试整合 Code Contracts到一些现有的代码中,到目前为止,大部分都很好。我面临的问题是,我已经在一个接口(interface)上设置了契约,并且一个实现将实现委托(delegate)给一个 Func<> ,它被传递到类的构造函数中,类似于以下内容:

[ContractClass(typeof(IFooContract))]
public interface IFoo
{
    object Bar();
}

[ContractClassFor(typeof(IFoo))]
public abstract class IFooContract : IFoo
{
    object IFoo.Bar()
    {
        Contract.Ensures(Contract.Result<object>() != null);
        throw new NotImplementedException();
    }
}

public class DelegatedFoo : IFoo
{
    public DelegatedFoo(Func<object> barImplementation)
    {
        Contract.Requires(barImplementation != null);
        _barImplementation = barImplementation;
    }
    private readonly Func<object> _barImplementation;

    [ContractInvariantMethod]
    private void ObjectInvariants()
    {
        Contract.Invariant(_barImplementation != null);
    }

    public object Bar()
    {
        //"ensures unproven: Contract.Result<object>() != null" here.
        return _barImplementation();
    }
}

静态分析器报告错误“ensures unproven: Contract.Result() != null”。我可以在 Func<> 上定义契约吗(以及在 Action<> 上的扩展)?

这是最好的解决方案吗?

public class DelegatedFoo : IFoo
{
    public DelegatedFoo(Func<object> barImplementation)
    {
        Contract.Requires(barImplementation != null);
        _barImplementation = barImplementation;
    }
    private readonly Func<object> _barImplementation;

    [ContractInvariantMethod]
    private void ObjectInvariants()
    {
        Contract.Invariant(_barImplementation != null);
    }

    public object Bar()
    {
        var result = _barImplementation();
        Contract.Assume(result != null);
        return result;
    }
}

最佳答案

那么,您总是可以控制Func<object>吗?实例传入?如果是这样,Func<object> 引用的每个函数参数需要有一个 Contract.Ensures(Contract.Result<object>() != null)定义后置条件。

如果你有一个 Action 也是一样的。参数,而不是。

此外,我绝对不会使用 Contract.Assume(result != null) .你确定你永远不会返回 null 吗?如果你这样做会发生什么?尝试将其更改为 Contract.Assert(result != null)反而。如果您可以控制 Func<object>参数并使用后置条件,那么您还应该能够在 public object Bar() 上指定后置条件方法并放弃对任何断言或假设的需要。

最后,您可能需要考虑添加 Contract.Ensures(_barImplementation == barImplementation)给你的 DelegatedFoo 的构造函数,不过,我想后置条件包含在定义的不变量中。我总是喜欢直截了当——这肯定不会有什么坏处,尤其是在涉及静态分析器的地方。

关于c# - 在 Func<> 上定义代码契约,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22238733/

相关文章:

c# - LINQ 等于 - 它在幕后调用什么?

c# - 为什么在禁用运行时检查时 FXCop 会引发针对 Contract 类的违规?

c# - 代码约定如何处理异常

c# - 如何防止代码契约自动创建前提条件检查?

c# - 在 C# 中从 Bing Map API 解析 JSON 代码

c# - TaskScheduler - 执行延续

c# - 我怎样才能调整窗口工作区的大小,然后更新其他窗口以反射(reflect)更改?

c# - 使用 AutoMapper 将 ICollection<Model> 映射到 List<ViewModel>

c# - 非空接口(interface)代码契约的实现——default(T) vs throw NotImplementedException

security - 代码契约(Contract)是否应该用于安全性?