2010-04-27 8 views
8

सभी मैं चाहता हूँ एक शब्दकोश जो मुझे जो कुंजी यह नहीं पा सके सिर्फ The given key was not present in the dictionary कह के बजाय, बताता है।"Verbose शब्दकोश" सी # में, 'ओवरराइड नए' यह [] या लागू IDictionary

मैंने संक्षेप में override new this[TKey key] के साथ उप-वर्ग करने पर विचार किया, लेकिन मुझे लगा कि यह थोड़ा हैकी है, इसलिए मैं आईडीकी इंटरफ़ेस को कार्यान्वित करने के साथ चला गया हूं, और सीधे एक आंतरिक शब्दकोश में सबकुछ पास कर रहा हूं, जिसमें केवल अतिरिक्त तर्क है सूचकांक:

public TValue this[TKey key] 
{ 
    get 
    { 
     ThrowIfKeyNotFound(key); 
     return _dic[key]; 
    } 
    set 
    { 
     ThrowIfKeyNotFound(key); 
     _dic[key] = value; 
    } 
} 
private void ThrowIfKeyNotFound(TKey key) 
{ 
    if(!_dic.ContainsKey(key)) 
     throw new ArgumentOutOfRangeException("Can't find key [" + key + "] in dictionary"); 
} 

क्या यह सही/एकमात्र तरीका है? इस पर नया क्या होगा [] वास्तव में वह बुरा हो?

उत्तर

10

एक विस्तार विधि के लिए बिल्कुल उपयुक्त की तरह लगता है

var data = new Dictionary<int, string> { { 123, "abc" } }; 
    Console.WriteLine(data.VerboseGetValue(123)); 
    Console.WriteLine(data.VerboseGetValue(456)); 
+0

मुझे बहुत खुशी है उन हूँ # 1 और # 2 ग्रह के दाईं ओर हैं :) – Benjol

1

आप ऐसा करना चाहते हैं, तो आप एक तरह से या किसी अन्य रूप में अपने खुद के रोल करने के लिए जा रहे हैं। लेकिन मैं सवाल करने जा रहा हूं कि आप ऐसा क्यों करना चाहते हैं? सफलता मामला -

+0

ठीक है, मैंने सोचा कि मैं ने कहा कि सवाल में क्यों। बल्कि सेटअप कहा, "जो मूल्य किया मैं गलत?" कर पुरुष से एक मेल प्राप्त करने से, मैं उसे खुद को इसे ठीक करने में सक्षम होने पसंद करते हैं। – Benjol

3
इसके बजाय ContainsKey कर और अंतर्निहित शब्दकोश को छूने से पहले कुंजी की उपस्थिति के लिए जाँच की

, क्यों इस तरह से काम नहीं

get { 
    try { 
     return _dic[key]; 
    } 
    catch (ArgumentOutOfRangeException) { 
     throw new ArgumentOutOfRangeException(......); 
    } 
} 

, आप केवल विफलता के मामले में अतिरिक्त जांच के लिए भुगतान , जो उम्मीद है कि अधिक आम है, एक अतिरिक्त शब्दकोश लुकअप करने की ज़रूरत नहीं है। यह पाने के लिए अच्छा है, लेकिन सेट अधिक डिफ़ॉल्ट है क्योंकि सेट के डिफ़ॉल्ट व्यवहार हमेशा काम करना है। यदि आप इसे नहीं चाहते हैं तो आपको पहले कुंजी के अस्तित्व की जांच करनी होगी।

public static class SomeUtilClass { 
    public static TValue VerboseGetValue<TKey, TValue>(
     this IDictionary<TKey, TValue> data, TKey key) 
    { 
     TValue result; 
     if (!data.TryGetValue(key, out result)) { 
      throw new KeyNotFoundException(
       "Key not found: " + Convert.ToString(key)); 
     } 
     return result; 
    } 
} 

यह तो आपके सभी मौजूदा शब्दकोशों पर काम करेंगे, जब भी आप VerboseGetValue फोन उदाहरण के लिए::

+0

+1 एक अपवाद हैंडलर असाधारण स्थिति को संभालने का सबसे अच्छा तरीका है। यही वह है जो वे हैं। :) – HiredMind

+1

@Stewart जब तक मैं गलत कर रहा हूँ, 'System.Collections.Generic.Dictionary' एक त्रुटि इंडेक्सर में जब कुंजी नहीं मिला था फेंक नहीं है, बजाय इसे नए मान के साथ चुपचाप जोड़ा जाता है। यद्यपि आपका दृष्टिकोण अभी भी गेटर के लिए काम करेगा। –

+0

@ जॉर्जेस डुपरॉन - आप बिल्कुल सही हैं। यह केवल मामले में काम करता है। मैं उदाहरण को संशोधित करूंगा। सेट केस के लिए, अतिरिक्त चेक अपरिहार्य है। – Stewart

संबंधित मुद्दे