0

基本上我想知道使用代码合同来确定 ConcurrentDictionary 中是否存在密钥是否是可接受的代码合同使用。这对我来说感觉不对,因为它不仅仅是参数检查,因为它取决于运行时字典的状态。

public class MyClass
{
    private ConcurrentDictionary<string, object> someItems = 
        new ConcurrentDictionary<string, object>();

    public object GetItem(string itemName)
    {
        Contract.Requires<ArgumentNullException>(!String.IsNullOrWhiteSpace(itemName));

        // ?? Is this a correct alternative to checking for null???
        Contract.Requires<KeyNotFoundException>(someItems.ContainsKey(itemName));

        return someItems[itemName];
    }
}

但如果可以的话,它是一种更简洁的方法,它有 2 个 Contract.Requires 和一个 return,而不是下面的传统方式。

public class MyClass
{
    private ConcurrentDictionary<string, object> someItems = 
        new ConcurrentDictionary<string, object>();

    public object GetItem(string itemName)
    {
        Contract.Requires<ArgumentNullException>(!String.IsNullOrWhiteSpace(itemName));

        // Traditional null check
        var item = someItems[itemName];

        if (item == null)
        {
            throw new KeyNotFoundException("Item " + itemName + " not found.");
        }

        return item;            
    }
}
4

1 回答 1

0

我觉得有点奇怪:类的内部状态(即someItems字典的内容)绝对不是合同的一部分。你可以这样使用它,但是合约检查应该让调用者知道到底出了什么问题。在这种情况下,调用者永远不会猜测哪些参数是允许的,哪些是不允许的——即使在得到KeyNotFoundException.

此外,在这种特殊情况下,如果在字典中找不到对象,则抛出异常看起来不一致,在我看来,返回更有意义null

顺便说一句,在您的第一个示例itemName中,在字典中搜索了两次。

于 2013-03-15T22:20:02.630 回答