如何从IDictionary <t,u =“”>?</t,>等接口派生时使用代码契约

时间:2010-10-03 03:14:35

标签: c# interface code-contracts

我正在编写的一个类实现IDictionary<string, object>。在我的CopyTo实现中,我想使用代码合同:Contract.Requires<ArgumentNullException>(array != null)

等内容

但是,我收到了这个警告(删除了一些名称空间以便于阅读):

方法“LuaDictionary.CopyTo(KeyValuePair<String,Object>[],Int32)”实现了接口方法“ICollection<KeyValuePair<String,Object>>.CopyTo(KeyValuePair<String,Object>[],Int32)”,因此无法添加Requires

我看到有一些相关问题,但它们似乎都与用户控制下的接口有关。显然,IDictionary<T, U>不在我的控制之下,因此我无法用ContractClassFor或其他类似的方式对其进行注释。

所以我在这里无法使用代码合约?如果是这样......主要是无赖......

2 个答案:

答案 0 :(得分:5)

这是一个无赖,但可以理解,因为使用您的类实例IDictionary<string, object>的客户端代码不应该满足IDictionary<string, object>不期望的前提条件。

您可以阅读提供给this SO question的答案,该答案链接并引用代码合同用户手册,您可以查看this article,以这种方式解释情况,然后继续提供一个简单的例子:

  

请注意,Liskov的替换原则适用于代码契约,其方式与普通类完全相同。利斯科夫的原则如下:

     

子类应始终可替代其基类。

     

就Code Contracts API而言,这意味着派生类(或实现基于契约的接口的类)不应期望更多的前置条件作为父类。

答案 1 :(得分:5)

请注意,IDictionary<K,V>已经拥有Requires:)

您可以在C:\Program Files (x86)\Microsoft\Contracts下查看类的现有合约DLL。

如果使用Reflector打开mscorlib.Contracts.dll,您可以查看集合类的合同; CopyTo有以下内容:

public void CopyTo(T[] array, int arrayIndex)
{
    Contract.Requires((bool)(array != null), null, "array != null");
    Contract.Requires((bool)(arrayIndex >= 0), null, "arrayIndex >= 0");
    Contract.Requires((bool)((arrayIndex + this.Count) <= array.Length), null, "arrayIndex + this.Count  <= array.Length");
}