2011-09-14 12 views
6

मुझे यकीन है कि अगर मैं गलत यहाँ या अगर यह समस्या दूर करनी होगी कुछ कर रहा हूँ नहीं कर रहा हूँ ...कोड संविदा: यह सुनिश्चित Unproven और आवश्यक Unproven

मैं एक कस्टम शब्दकोश आवरण वर्ग है और यहाँ एक टुकड़ा है आवश्यक कोड का।

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

एकमात्र कारण मैं ContainsKey के लिए लाइन जोड़ा है, क्योंकि मैं निम्न चेतावनी संदेश मिल गया (और अब भी करते हैं): Codecontracts: ensures unproven: !Contract.Result<bool>() || @this.Count > 0। मैं इस लाइन को हटा सकता हूं और अभी भी समान ISSUE प्राप्त कर सकता हूं!

इन मुद्दों से छुटकारा पाने के लिए मैं यहां क्या करूँ?


अद्यतन:

मैं भी (के रूप में सुझाव दिया) की कोशिश की ...

public Boolean ContainsKey(TKey key) 
{ 
    Contract.Requires(Count == 0 || InternalDictionary.ContainsKey(key)); 
    Contract.Ensures(!Contract.Result<bool>() || Count > 0); 

    return InternalDictionary.ContainsKey(key); 
} 

चेतावनी 5 विधि 'My.Collections.Generic.ReadOnlyDictionary 2.ContainsKey(type parameter.TKey)' implements interface method 'System.Collections.Generic.IDictionary 2.ContainsKey (प्रकार पैरामीटर.TKey) ', इस प्रकार जोड़ना आवश्यक नहीं है।

+0

ध्यान दें कि आपकी समस्या की जड़ यह है कि यह विधि यह वादा कर रही है कि प्रत्येक कुंजी मिल जाएगी, और इसका वास्तव में कोई नियंत्रण नहीं है। –

उत्तर

1

स्पष्ट रूप से मैं अनुबंध के बिंदु को समझ नहीं पा रहा हूं। अनुबंध

Contract.Ensures(!Contract.Result<bool>() || Count > 0); 

आप क्या कहने की कोशिश कर रहे हैं? आप न तो गारंटी दे सकते हैं कि शब्दकोश में कुंजी है, न ही शब्दकोश में कोई भी मान है। तो यह अनुबंध हमेशा पूरा नहीं किया जा सकता है। यही वही है जो सत्यापनकर्ता आपको बता रहा है: यह साबित नहीं कर सकता कि यह कथन आप सत्य होने का वादा कर रहे हैं।

सबसे अच्छा आप यह सुनिश्चित कर सकते हैं कि वापसी मान true है या वापसी मान false है और वह Count शून्य से अधिक या शून्य के बराबर है लेकिन इस तरह के एक अनुबंध के बिंदु क्या

? कॉलर पहले से ही यह जानता है।

यह देखते हुए कि, मैं यहां अनुबंध से परेशान नहीं हूं।

+0

मेरे प्रश्न में मैंने कहा कि एकमात्र कारण मैंने जोड़ा कि अनुबंध था क्योंकि चेतावनी संदेश ने मुझे बताया था। मुझे इसके साथ या इसके बिना एक ही चेतावनी मिलती है, और स्पष्ट रूप से मैं यह भी समझ में नहीं आता कि यह क्या कहने की कोशिश कर रहा है। – michael

+0

@ माइकल: फिर से शुरू करें। क्या यह पहला अनुबंध नहीं था? –

+0

मूल रूप से, मेरे पास कोड में कोई अनुबंध नहीं था। कोडकंट्रैक्ट्स ने शिकायत की और मैंने जो कहा, उसके कारण मैंने वहां अनुबंध रखा। बाद में, मुझे एक ही चेतावनी संदेश मिलता है। असल में, भले ही विधि में ** कोई ** अनुबंध कोड न हो, फिर भी यह वही चेतावनी देता है। – michael

5

"मेरे पास एक कस्टम शब्दकोश रैपर वर्ग है" - जो IDictionary<TKey, TValue> लागू करता है। इंटरफ़ेस विधियां अनुबंध निर्दिष्ट कर सकती हैं, और उन्हें लागू करने वाले वर्ग विधियों को अनुबंधों को पूरा करना होगा। इस मामले में, IDictionary<TKey, TValue>.ContainsKey(TKey) अनुबंध आप के बारे में पूछ रहे हैं है:

Contract.Ensures(!Contract.Result<bool>() || this.Count > 0); 

तार्किक रूप से, !a || b (a तात्पर्य b) a ===> b के रूप में पढ़ा जा सकता है और का उपयोग कर कि, हम अंग्रेजी को यह अनुवाद कर सकते हैं:

If ContainsKey() returns true, the dictionary must not be empty. 

यह एक पूरी तरह से समझदार आवश्यकता है। एक खाली शब्दकोश में चाबियाँ रखने का दावा नहीं करना चाहिए। यह वह है जो आपको साबित करने की आवश्यकता है।

यहां नमूने DictionaryWrapper वर्ग कि Contract.Ensures कहते हैं वादा है कि Count के कार्यान्वयन विस्तार innerDictionary.Count के बराबर किया जा रहा है एक कठिन गारंटी नहीं है कि अन्य तरीकों पर भरोसा कर सकते है।यह एक समान Contract.EnsuresContainsKey जोड़ता है ताकि 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(); 
    } 
} 
+0

+1 यदि फ़ंक्शन का परिणाम सत्य नहीं हो सकता है। मैंने उन सशर्त अनुबंधों पर ठोकर खाई और उस पहचान को भूल गए जो मेरी अलग गणित कक्षाओं xD से तात्पर्य है। – julealgon