2009-12-16 7 views
13

मूल रूप से की अनुमति देगा की आवश्यकता है, मैं कुछ इस तरह हैं:सी # - एक IDictionary कार्यान्वयन कि एक अशक्त कुंजी

Dictionary<object, string> dict = new Dictionary<object, string>(); 
dict.Add(null, "Nothing"); 
dict.Add(1, "One"); 

वहाँ रहे हैं किसी भी आधार वर्ग पुस्तकालय है कि इस अनुमति देते हैं में बनाया गया? पिछला कोड जोड़ते समय पिछले कोड रनटाइम पर अपवाद फेंक देगा।

धन्यवाद

+0

बस उत्सुक जहाँ आप इस की ज़रूरत है? धन्यवाद –

उत्तर

11

आप अशक्त उपयोग करने से बचें और एक विशेष सिंगलटन मूल्य वर्ग वही चीज़ बना सकते हैं। उदाहरण के लिए:

public sealed class Nothing 
{ 
    public static readonly Nothing Value = new Nothing(); 
    private Nothing() {} 
} 

Dictionary<object, string> dict = new Dictionary<object, string>(); 
dict.add(Nothing.Value, "Nothing"); 
dict.add(1, "One"); 

यह दृष्टिकोण काम करने के लिए असफल हो अगर आप अपने संग्रह और अधिक दृढ़ता से टाइप किया करने का इरादा होगा - के उदाहरण आप कुंजी एक स्ट्रिंग होना चाहता हूँ के लिए मान लीजिए। चूंकि स्ट्रिंग को सील कर दिया गया है, इसलिए आप इसके लिए "विशेष मूल्य" विकल्प बनाने के लिए प्राप्त नहीं कर सकते हैं। आपके विकल्प थोड़ा और जटिल हो जाते हैं। आप:

  1. "खाली"/"शून्य" केस का प्रतिनिधित्व करने के लिए कुछ विशेष स्थिर मूल्य बनाएं। हैकी की तरह और निश्चित रूप से भ्रम के लिए एक रास्ता है। यह एक व्यावहारिक दृष्टिकोण हो सकता है यदि शब्दकोश कुछ कार्यान्वयन वर्ग के लिए पूरी तरह से निजी है और आप कुछ जगहों पर कुंजी का अनुवाद कैसे करते हैं, इस बारे में ज्ञान फैलाने से बचने के लिए आप कुछ एनकोड/डिकोड उपयोगिता विधियां लिख सकते हैं।
  2. IDictionary का अपना कार्यान्वयन बनाएं जो आंतरिक रूप से एक शब्दकोश <> उदाहरण के लिए प्रतिनिधि करता है - शून्य के मामले को छोड़कर। यह IDictionary <> इंटरफ़ेस के लिए प्रलेखित अपेक्षाओं का उल्लंघन करता है जो कहता है कि शून्य कुंजी को अपवाद फेंकना चाहिए। लेकिन अगर आप अपनी वास्तविक समस्या को हल करने का एकमात्र तरीका है तो आप इससे दूर हो सकते हैं। यह केवल तभी काम करता है जब आप शब्दकोश का उदाहरण बनाते हैं और बनाते हैं।
  3. शब्दकोश में "शून्य" कुंजी संग्रहीत किए बिना अपनी समस्या का समाधान करने का एक तरीका खोजें। उदाहरण के लिए, शब्दकोश में शून्य कुंजी को पॉप्युलेट करने पर विचार न करें और इसके साथ निपटने के लिए कुछ विशेष केस तर्क रखें। कुंजी को हड़ताली होना चाहिए और अंतर्निहित कार्यान्वयन के साथ काम करने के लिए तुलनीय होना चाहिए, यही कारण है कि सामान्य रूप से शून्य निषिद्ध है।

एक तरफ के रूप में, क्या आपकी शब्दकोश कुंजी को वास्तव में object होने की कुंजी की आवश्यकता है? यह संदर्भ समानता के कारण सूक्ष्म बग का कारण बन सकता है जहां आप तुलना के आधार के रूप में मूल्यांकन के बराबर बराबर() का मूल्यांकन कर सकते हैं।

+0

इसके लिए आवेदन घटक एक उपयोगकर्ता नियंत्रण C1FlexGrid.ImageMap है जो मूल रूप से किसी छवि में ग्रिड में संग्रहीत मानों को मैप करने के लिए है। असल में, मेरे पास डेटा पर नियंत्रण नहीं है, उनमें से कुछ शून्य हैं। – Clyde

+0

तो दुर्भाग्य से मैं कुछ भी सुझाव जैसे मॉक ऑब्जेक्ट का उपयोग नहीं कर सकता। – Clyde

+0

हालांकि, == बनाम बराबर चेतावनी के लिए धन्यवाद .... आपने मुझे एक अलग समस्या को ट्रैक करने में कुछ समय बचाया .. – Clyde

2

NameValueCollection एक शून्य कुंजी ले सकता है लेकिन यह IDictionary को लागू नहीं करता है।

class MyDictionary : DictionaryBase { 
    private readonly object nullKey = new object(); 

    void Add(object key, string value) { 
     if (key == null) { key = nullKey; } 
     .. call base methods 
    } 

} 
5

कैसे इस बारे में: यह तथापि DictionaryBase से निकाले जाते हैं और जोड़ें/निकालें/Indexers आदि कि बस कुछ की तरह में बनाया के साथ अशक्त की जगह उपलब्ध कराने के लिए बहुत आसान हो सकता है?

public class NullableDictionnary<T1, T2> : Dictionary<T1, T2> 
{ 
    T2 null_value; 

    public T2 this[T1 key] 
    { 
     get 
     { 
      if (key == null) 
      { return null_value; } 
      return base[key]; 
     } 
     set 
     { 
      if (key == null) 
      { null_value = value; } 
      else 
      { base[key] = value; } 
     } 
    } 
} 
+8

उन सभी अन्य कार्यों से सावधान रहें जिन्हें आपने अभी अवैध कर दिया है - गणना करें, जोड़ें, साफ़ करें, इसमें शामिल हैं, शामिल हैं, वैल्यू, इत्यादि ... मेरा मतलब है, अगर आप सिर्फ हैकिंग कर रहे हैं, ठीक है, लेकिन मुझे एक बनाने का विचार नापसंद है यदि आप ऐसा करने जा रहे हैं तो "NullableDictionary" कक्षा। जब एक हैक स्पष्ट रूप से एक हैक है, तो आप इसके बाद थोड़ा सा होने की संभावना कम कर सकते हैं। – phillipwei

+1

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

0

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

हो सकता है कि एक नया वर्ग


public class ObjectEntry 
{ 
    public object objRef; 
    public string desc; 

    public ObjectEntry(object objectReference) 
    { 
     objRef = objectReference; 
     if (objRef = null) {desc = "Nothing";} 
     else {desc = objRef.Description;} //or whatever info you can get from a proper objRef value 
    } 
} 

newObj = new ObjectEntry(null); 
dict.add(newObj, newObj.desc); 
0

Dicionary का एक अलग कार्यान्वयन के लिए कोई ज़रूरत नहीं पैदा करते हैं।

मेरा उत्तर यहाँ पर एक नज़र डालें: https://stackoverflow.com/a/22261282/212272

आप भी अपने शब्दकोश दृढ़ता से टाइप किया रखने के लिए सक्षम हो जाएगा:

var dict = new Dictionary<NullObject<int?>, string>(); 
dict[1] = "one int"; 
dict[null] = "null int"; 

Assert.AreEqual("one int", dict[1]); 
Assert.AreEqual("null int", dict[null]); 
संबंधित मुद्दे