2013-03-15 41 views
0

基本上我想知道是否使用代碼合約來確定ConcurrentDictionary中是否存在密鑰是代碼合同的可接受使用。它不適合我,因爲它不僅僅是參數檢查,因爲它取決於運行時字典的狀態。正確使用CodeContract需要

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和一個返回,在低於傳統方式清潔方法。

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;    
    } 
} 

回答

0

看起來有點奇給我:類(即someItems詞典的內容)的內部狀態絕對是一個合同的一部分。你可以這樣使用它,但合同檢查應該讓來電者知道究竟是什麼錯誤。在這種情況下,調用者永遠不會猜測哪些參數是允許的,哪些不是 - 即使在獲得KeyNotFoundException後。

此外,在這種特殊情況下,如果在字典中找不到對象,則引發異常並不一致,在我看來,返回null會更有意義。

順便說一下,在您的第一個示例中itemName在字典中搜索兩次。

+0

KeyNotFoundException對一個方法GetItem有一個參數幾乎告訴我什麼是錯誤的;然而,我傾向於對這個特殊的測試本身並不是合同有同樣的感覺。拋出與返回null是API的設計考慮因素,而不是真正的代碼合同問題。總的來說,我認爲你已經用良好的觀點驗證了我的同樣關切。謝謝! – GoClimbColorado 2013-03-16 18:00:52