【问题标题】:Add contract to interface implementation将合约添加到接口实现
【发布时间】:2009-09-06 11:48:41
【问题描述】:

我了解我无法在接口实现上添加先决条件。我必须创建一个合同类,在其中定义界面所见元素的合同。

但是在以下情况下,如何在接口定义级别不知道的实现的内部状态上添加契约?

[ContractClass(typeof(IFooContract))]
interface IFoo
{
  void Do(IBar bar);
}

[ContractClassFor(typeof(IFoo))]
sealed class IFooContract : IFoo
{
  void IFoo.Do(IBar bar)
  {
    Contract.Require (bar != null);

    // ERROR: unknown property
    //Contract.Require (MyState != null);
  }
}

class Foo : IFoo
{
  // The internal state that must not be null when Do(bar) is called.
  public object MyState { get; set; }

  void IFoo.Do(IBar bar)
  {
    // ERROR: cannot add precondition
    //Contract.Require (MyState != null);

    <...>
  }
}

【问题讨论】:

    标签: c# interface contract


    【解决方案1】:

    您不能 - 该后置条件不适用于 IFoo 的所有实现,因为它没有在 IFoo 中声明。您只能引用接口的成员(或它扩展的其他接口)。

    您应该可以将它添加到 Foo,因为您添加的是 后置条件 (Ensures) 而不是 前置条件 (Requires )。

    您不能添加特定于实现的前提条件,因为这样调用者将无法知道他们是否会违反合同:

    public void DoSomething(IFoo foo)
    {
        // Is this valid or not? I have no way of telling.
        foo.Do(bar);
    }
    

    基本上,合同不允许对调用者“不公平” - 如果调用者违反了先决条件,则应始终表明存在错误,而不是他们无法预测的情况。

    【讨论】:

    • 现在不能——但我回答的后半部分说明了为什么你不能这样做。
    • 这是合同的限制还是我的设计问题?我应该创建另一个包含我需要检查的属性的界面吗?
    • 这是您的设计中的一个缺陷。如果调用者无法判断他们是否违反了您的合同,他们如何使用您的界面?
    • @JonSkeet 我打算问一个类似的问题,但我更愿意在评论中问你。当您说“您不能添加特定于实现的前提条件,因为 [...]”时,您认为代码合同不会支持此用例,因为不同的实现不可能需要不同的前置条件。我错了吗?但归根结底,实现可能无论如何都需要特定的先决条件。例如,I接口的实现需要访问数据库,因此它需要一个连接字符串,但这不能被合约类反映
    • @JonSkeet 这种情况不是支持实施前提条件的好论据吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-13
    • 1970-01-01
    相关资源
    最近更新 更多