我正在编写的一个类实现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
或其他类似的方式对其进行注释。
所以我在这里无法使用代码合约?如果是这样......主要是无赖......
答案 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");
}