mic*_*ael 6 c# idictionary code-contracts
我不确定我在这里做错了什么,或者是否需要修复......
我有一个自定义的Dictionary包装类,这里是一段必要的代码片段.
public int Count
{
get
{
Contract.Ensures(Contract.Result<int>() >= 0);
return InternalDictionary.Count;
}
}
public bool ContainsKey(TKey key)
{
//This contract was suggested by the warning message, if I remove it
//I still get the same warning...
Contract.Ensures(!Contract.Result<bool>() || Count > 0);
return InternalDictionary.ContainsKey(key);
}
Run Code Online (Sandbox Code Playgroud)
唯一的原因,我添加了的containsKey行是因为我得到了下面的警告消息(现在仍然如此)Codecontracts: ensures unproven: !Contract.Result<bool>() || @this.Count > 0.我可以删除这一行并仍然得到相同的问题!
我该怎么做才能摆脱这些问题?
更新:
我也试过(按照建议)......
public Boolean ContainsKey(TKey key)
{
Contract.Requires(Count == 0 || InternalDictionary.ContainsKey(key));
Contract.Ensures(!Contract.Result<bool>() || Count > 0);
return InternalDictionary.ContainsKey(key);
}
Run Code Online (Sandbox Code Playgroud)
警告5方法'My.Collections.Generic.ReadOnlyDictionary
2.ContainsKey(type parameter.TKey)' implements interface method 'System.Collections.Generic.IDictionary2.ContainsKey(type parameter.TKey)',因此无法添加Requires.
小智 5
"我有一个自定义的字典包装类" - 实现IDictionary<TKey, TValue>.接口方法可以指定契约,实现它们的类方法必须符合契约.在这种情况下,IDictionary<TKey, TValue>.ContainsKey(TKey)您要询问的合同是:
Contract.Ensures(!Contract.Result<bool>() || this.Count > 0);
Run Code Online (Sandbox Code Playgroud)
逻辑上,!a || b可以读作a ===> b(a暗示b),并使用它,我们可以将其翻译为英语:
If ContainsKey() returns true, the dictionary must not be empty.
Run Code Online (Sandbox Code Playgroud)
这是一个非常明智的要求.空字典不得声称包含密钥.这是你需要证明的.
这是一个示例DictionaryWrapper类,它增加Contract.Ensures了承诺,Count等于的实现细节innerDictionary.Count是其他方法可以依赖的硬保证.它增加了一个类似的Contract.Ensures,ContainsKey以便IDictionary<TKey, TValue>.TryGetValue合同也可以验证.
public class DictionaryWrapper<TKey, TValue> : IDictionary<TKey, TValue>
{
IDictionary<TKey, TValue> innerDictionary;
public DictionaryWrapper(IDictionary<TKey, TValue> innerDictionary)
{
Contract.Requires<ArgumentNullException>(innerDictionary != null);
this.innerDictionary = innerDictionary;
}
[ContractInvariantMethod]
private void Invariant()
{
Contract.Invariant(innerDictionary != null);
}
public void Add(TKey key, TValue value)
{
innerDictionary.Add(key, value);
}
public bool ContainsKey(TKey key)
{
Contract.Ensures(Contract.Result<bool>() == innerDictionary.ContainsKey(key));
return innerDictionary.ContainsKey(key);
}
public ICollection<TKey> Keys
{
get
{
return innerDictionary.Keys;
}
}
public bool Remove(TKey key)
{
return innerDictionary.Remove(key);
}
public bool TryGetValue(TKey key, out TValue value)
{
return innerDictionary.TryGetValue(key, out value);
}
public ICollection<TValue> Values
{
get
{
return innerDictionary.Values;
}
}
public TValue this[TKey key]
{
get
{
return innerDictionary[key];
}
set
{
innerDictionary[key] = value;
}
}
public void Add(KeyValuePair<TKey, TValue> item)
{
innerDictionary.Add(item);
}
public void Clear()
{
innerDictionary.Clear();
}
public bool Contains(KeyValuePair<TKey, TValue> item)
{
return innerDictionary.Contains(item);
}
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
innerDictionary.CopyTo(array, arrayIndex);
}
public int Count
{
get
{
Contract.Ensures(Contract.Result<int>() == innerDictionary.Count);
return innerDictionary.Count;
}
}
public bool IsReadOnly
{
get
{
return innerDictionary.IsReadOnly;
}
}
public bool Remove(KeyValuePair<TKey, TValue> item)
{
return innerDictionary.Remove(item);
}
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
return innerDictionary.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return innerDictionary.GetEnumerator();
}
}
Run Code Online (Sandbox Code Playgroud)
坦白说,我不明白合同的意义。合同是
Contract.Ensures(!Contract.Result<bool>() || Count > 0);
Run Code Online (Sandbox Code Playgroud)
你想说什么?您既不能保证字典包含键,也不能保证字典包含任何值。所以这个合同并不总是能够得到满足。这就是验证者告诉你的:它无法证明你承诺的这个陈述是真实的。
最好你能确保返回值是true或返回值false大于Count零或等于零但是这样的合同有什么意义呢?呼叫者已经知道这一点。
鉴于此,我根本不会在这里签订合同。