C# में Dictionary vs Hashtable: Dictionary क्यों बेहतर है?

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

Dictionary vs Hashtable: C# कलेक्शंस की जंग

\n\n

एक परिदृश्य की कल्पना करें: आप C# में कोड लिख रहे हैं, और आपको डेटा को की-वैल्यू के रूप में तेज़ी से सेव और एक्सेस करना है। आप डॉक्यूमेंटेशन खोलते हैं और दो समान क्लास देखते हैं — Dictionary और Hashtable। दोनों "की-वैल्यू" सिद्धांत पर काम करते हैं, दोनों तेज़ डेटा एक्सेस का वादा करते हैं। लेकिन किसे चुनें?

\n\n

अगर आपने यह सवाल पूछा है, तो आप अकेले नहीं हैं। Stack Overflow पर "C# में Hashtable की तुलना में Dictionary को क्यों पसंद किया जाता है?" विषय पर हज़ारों व्यूज़ और सैकड़ों वोट हैं। और आज हम इस सवाल का हमेशा के लिए जवाब देंगे। स्पॉयलर: Dictionary लगभग हमेशा जीतता है। लेकिन आइए जानें क्यों।

\n\n

इतिहास में एक झलक: Hashtable कहाँ से आया?

\n\n

इस मुकाबले को समझने के लिए, C# के इतिहास में झाँकना ज़रूरी है। जब .NET प्लेटफ़ॉर्म पहली बार आया (वर्जन 1.0), डेवलपर्स के पास System.Collections नेमस्पेस से Hashtable क्लास उपलब्ध था। यह एक क्लासिक हैश टेबल थी, जो किसी भी ऑब्जेक्ट को स्टोर कर सकती थी। अच्छा लगता है, है ना? लेकिन एक समस्या थी — टाइपिंग का अभाव।

\n\n

.NET 2.0 के आगमन और जेनेरिक्स (generics) के साथ, Microsoft ने एक नया कलेक्शन पेश किया — Dictionary<TKey, TValue> जो System.Collections.Generic नेमस्पेस में है। और यहीं से असली जादू शुरू हुआ।

\n\n

टाइप-सेफ्टी: Dictionary का सबसे बड़ा फायदा

\n\n

आइए एक ठोस कोड उदाहरण देखें। Hashtable के साथ काम कैसा दिखता है:

\n\n
// पुराना तरीका: Hashtable\nHashtable hashtable = new Hashtable();\nhashtable.Add("की1", 123);\nhashtable.Add("की2", "स्ट्रिंग"); // गलती? नहीं, कंपाइल हो जाएगा!\nhashtable.Add(456, "एक और स्ट्रिंग"); // की भी कोई भी ऑब्जेक्ट हो सकता है\n\n// अब डेटा निकालने की कोशिश करते हैं\nint value = (int)hashtable["की2"]; // उफ़! रनटाइम पर InvalidCastException!
\n\n

समस्या दिखी? Hashtable किसी भी प्रकार को स्वीकार करता है — की और वैल्यू दोनों के लिए। कंपाइलर कोई भी गलती छोड़ देगा, और आपको इसके बारे में प्रोग्राम चलने पर ही पता चलेगा। यह उन बग्स का सीधा रास्ता है जिन्हें पकड़ना मुश्किल है।

\n\n

अब Dictionary देखें:

\n\n
// नया, सही तरीका: Dictionary\nDictionary<string, int> dictionary = new Dictionary<string, int>();\ndictionary.Add("की1", 123);\n// dictionary.Add("की2", "स्ट्रिंग"); // कंपाइल एरर! टाइप मैच नहीं करता\n// dictionary.Add(456, "एक और स्ट्रिंग"); // एरर — की string होनी चाहिए\n\n// बिना टाइप कास्टिंग के डेटा निकालें\nint value = dictionary["की1"]; // साफ, सुरक्षित, सुंदर
\n\n

Dictionary टाइप-सेफ है। आप स्पष्ट रूप से बताते हैं कि की और वैल्यू के लिए कौन से टाइप होंगे। कंपाइलर बिल्ड के समय इसकी जाँच करता है। रनटाइम पर कोई अप्रत्याशित अपवाद नहीं — कोड या तो काम करेगा या कंपाइल नहीं होगा।

\n\n

प्रदर्शन: कौन तेज़ है?

\n\n

दूसरा महत्वपूर्ण पहलू प्रदर्शन है। और यहाँ Dictionary फिर से आगे है। क्यों? इसका कारण है बॉक्सिंग (boxing) और अनबॉक्सिंग (unboxing)।

\n\n

जब आप Hashtable के साथ काम करते हैं, तो सभी वैल्यू टाइप (int, double, struct आदि) ऑब्जेक्ट में बॉक्स हो जाते हैं। इससे गार्बेज कलेक्टर पर लोड बढ़ता है और काम धीमा हो जाता है। आइए व्यवहार में जाँच करें:

\n\n
// Hashtable: बॉक्सिंग/अनबॉक्सिंग\nHashtable ht = new Hashtable();\nStopwatch sw = Stopwatch.StartNew();\nfor (int i = 0; i < 1000000; i++)\n{\n    ht.Add(i, i); // हर int object में बॉक्स होता है\n}\nsw.Stop();\nConsole.WriteLine($"Hashtable जोड़ना: {sw.ElapsedMilliseconds} मि.से.");\n\n// Dictionary: बिना बॉक्सिंग के\nDictionary<int, int> dict = new Dictionary<int, int>();\nsw.Restart();\nfor (int i = 0; i < 1000000; i++)\n{\n    dict.Add(i, i); // कोई बॉक्सिंग नहीं — सीधे int के साथ काम\n}\nsw.Stop();\nConsole.WriteLine($"Dictionary जोड़ना: {sw.                

ब्लॉग

पुस्तक अनुशंसाएँ