क्या TryGetValue की तुलना में C # शब्दकोशों का उपयोग करने का एक बेहतर तरीका है?


19

मैं खुद को अक्सर ऑनलाइन प्रश्नों की तलाश करता हूं, और कई समाधानों में शब्दकोश शामिल हैं। हालांकि, जब भी मैं उन्हें लागू करने की कोशिश करता हूं, मुझे अपने कोड में यह भयानक रीच मिलता है। हर बार उदाहरण के लिए मैं एक मूल्य का उपयोग करना चाहता हूं:

int x;
if (dict.TryGetValue("key", out x)) {
    DoSomethingWith(x);
}

यह कोड की 4 पंक्तियाँ अनिवार्य रूप से निम्नलिखित करने के लिए है: DoSomethingWith(dict["key"])

मैंने सुना है कि बाहर कीवर्ड का उपयोग करना एक विरोधी पैटर्न है क्योंकि यह फ़ंक्शन को उनके मापदंडों को म्यूट करता है।

इसके अलावा, मुझे खुद को अक्सर "उलट" शब्दकोश की आवश्यकता होती है, जहां मैं कुंजी और मूल्यों को फ्लिप करता हूं।

इसी तरह, मैं अक्सर एक शब्दकोश में आइटम के माध्यम से पुनरावृति करना चाहता हूं और यह बेहतर करने के लिए खुद को सूचियों या मूल्यों को सूचियों आदि में परिवर्तित करना चाहता हूं।

मुझे लगता है कि शब्दकोशों का उपयोग करने का लगभग हमेशा एक बेहतर, अधिक सुरुचिपूर्ण तरीका है, लेकिन मैं नुकसान में हूं।


7
अन्य तरीके मौजूद हो सकते हैं, लेकिन मैं आम तौर पर एक मूल्य प्राप्त करने की कोशिश करने से पहले एक ContainsKey का उपयोग करता हूं ।
रॉबी डी

2
सच में, कुछ अपवादों के साथ, यदि आप जानते हैं कि आपके शब्दकोश कुंजी समय से आगे हैं, वहाँ शायद है एक बेहतर तरीका। यदि आप नहीं जानते हैं, तो तानाशाह की चाबियाँ आम तौर पर बिल्कुल भी हार्ड-कोड नहीं होनी चाहिए। शब्दकोश अर्ध-संरचित वस्तुओं या डेटा के साथ काम करने के लिए उपयोगी होते हैं जहां फ़ील्ड कम से कम आवेदन के लिए अधिक से अधिक ऑर्थोगोनल होते हैं। IMO, उन फ़ील्ड्स को संबंधित व्यवसाय / डोमेन अवधारणाओं के जितना करीब पाता है, उतने ही उपयोगी शब्दकोश उन अवधारणाओं के साथ काम करने के लिए बन जाते हैं।
svidgen 17

6
@ रोबीडी: आपको सावधान रहना होगा जब आप ऐसा करते हैं, हालांकि ऐसा करने से दौड़ की स्थिति बन जाती है। यह संभव है कि कुंजी को ContainsKey को कॉल करने और मूल्य प्राप्त करने के बीच हटाया जा सकता है।
whatsisname

12
@whatsisname: उन शर्तों के तहत, एक समवर्ती छायांकन अधिक उपयुक्त होगा। System.Collections.Genericनाम स्थान में संग्रह थ्रेड-सुरक्षित नहीं हैं
रॉबर्ट हार्वे

4
एक अच्छा 50% समय मैं किसी को एक का उपयोग करते हुए देखता हूं Dictionary, जो वे वास्तव में चाहते थे वह एक नया वर्ग था। उन 50% (केवल) के लिए, यह एक डिजाइन गंध है।
ब्लूराजा - डैनी Pflughoeft

जवाबों:


23

शब्दकोश (C # या अन्यथा) बस एक कंटेनर हैं जहां आप एक कुंजी के आधार पर एक मूल्य देखते हैं। कई भाषाओं में इसे अधिक सही ढंग से मानचित्र के रूप में पहचाना जाता है जिसमें सबसे सामान्य कार्यान्वयन हैशपॉप है।

विचार करने के लिए समस्या यह है कि क्या होता है जब एक कुंजी मौजूद नहीं होती है। कुछ भाषाओं में वापस लौट कर व्यवहार करते हैं nullया nilया कुछ अन्य समान मूल्य। चुपचाप एक मूल्य के लिए डिफ़ॉल्ट रूप से आपको सूचित करने के बजाय कि एक मूल्य मौजूद नहीं है।

बेहतर या बदतर के लिए, सी # लाइब्रेरी डिजाइनर व्यवहार से निपटने के लिए एक मुहावरे के साथ आए। उन्होंने तर्क दिया कि जो मान मौजूद नहीं है, उसे देखने के लिए डिफ़ॉल्ट व्यवहार अपवाद को फेंकना है। यदि आप अपवादों से बचना चाहते हैं, तो आप Tryवेरिएंट का उपयोग कर सकते हैं । यह वही दृष्टिकोण है जो वे पूर्णांक या दिनांक / समय ऑब्जेक्ट में तार को पार्स करने के लिए उपयोग करते हैं। अनिवार्य रूप से, प्रभाव इस प्रकार है:

T count = int.Parse("12T45"); // throws exception

if (int.TryParse("12T45", out count))
{
    // Does not throw exception
}

और उस शब्दकोष को आगे बढ़ाया, जिसका अनुक्रमणिका प्रतिनिधि को निम्नलिखित में से Get(index):

var myvalue = dict["12345"]; // throws exception
myvalue = dict.Get("12345"); // throws exception

if (dict.TryGet("12345", out myvalue))
{
    // Does not throw exception
}

यह केवल भाषा के डिजाइन का तरीका है।


क्या outचर को हतोत्साहित किया जाना चाहिए ?

C # उनके पास होने वाली पहली भाषा नहीं है, और विशिष्ट परिस्थितियों में उनका उद्देश्य है। यदि आप एक उच्च समवर्ती प्रणाली का निर्माण करने का प्रयास कर रहे हैं, तो आप outसमवर्ती सीमाओं पर चर का उपयोग नहीं कर सकते हैं।

कई मायनों में, अगर कोई मुहावरा है जो भाषा और कोर लाइब्रेरी प्रदाताओं द्वारा जासूसी करता है, तो मैं अपने एपीआई में उन मुहावरों को अपनाने की कोशिश करता हूं। यह एपीआई को उस भाषा में अधिक सुसंगत और घर पर महसूस कराता है। तो रूबी में लिखी एक विधि C #, C, या पायथन में लिखी गई विधि की तरह नहीं लग रही है। प्रत्येक के पास कोड बनाने का एक पसंदीदा तरीका है, और इसके साथ काम करने से आपके एपीआई के उपयोगकर्ताओं को इसे और अधिक तेज़ी से जानने में मदद मिलती है।


क्या मानचित्र सामान्य रूप से प्रतिरूप हैं?

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

यदि आपके पास द्वि-दिशात्मक मानचित्रण मूल्यों की बहुत छोटी सूची है, तो आपको केवल टुपल्स की सूची की आवश्यकता हो सकती है। या संरचनाओं की एक सूची, जहां आप मानचित्रण के दोनों ओर पहला मैच आसानी से पा सकते हैं।

समस्या डोमेन के बारे में सोचें, और नौकरी के लिए सबसे उपयुक्त उपकरण चुनें। यदि कोई नहीं है, तो इसे बनाएं।


4
"तब आपको केवल टुपल्स की एक सूची की आवश्यकता हो सकती है। या संरचना की एक सूची, जहाँ आप मैपिंग के दोनों ओर पहला मैच आसानी से पा सकते हैं।" - यदि छोटे सेट के लिए अनुकूलन हैं, तो उन्हें लाइब्रेरी में बनाया जाना चाहिए, न कि उपयोगकर्ता कोड में रबर-स्टैम्प।
Blrfl

यदि आप tuples या एक शब्दकोश की सूची चुनते हैं, तो यह एक कार्यान्वयन विवरण है। यह आपके समस्या डोमेन को समझने और नौकरी के लिए सही उपकरण का उपयोग करने का सवाल है। जाहिर है, एक सूची मौजूद है और एक शब्दकोश मौजूद है। सामान्य स्थिति के लिए, शब्दकोश सही है, लेकिन हो सकता है कि एक या दो अनुप्रयोगों के लिए आपको सूची का उपयोग करने की आवश्यकता हो।
बेरिन लोरिट्श

3
यह है, लेकिन यदि व्यवहार अभी भी समान है, तो यह दृढ़ संकल्प पुस्तकालय में होना चाहिए। मैंने अन्य भाषाओं में कंटेनरों के कार्यान्वयन को चलाया है जो कि एल्गोरिदम को बदल देगा यदि एक प्राथमिकता बताई जाए कि प्रविष्टियों की संख्या छोटी होगी। मैं आपके उत्तर से सहमत हूं, लेकिन एक बार यह समझ में आ जाने के बाद, यह एक पुस्तकालय में होना चाहिए, शायद एक स्मॉलबिडीयूरोनॉफ़ल के रूप में।
Blrfl

5
"बेहतर या बदतर के लिए, सी # लाइब्रेरी डिजाइनर व्यवहार से निपटने के लिए एक मुहावरे के साथ आए।" - मुझे लगता है कि आप सिर पर कील मारते हैं: वे एक मुहावरे के साथ "ऊपर आए", इसके बजाय एक मौजूदा व्यापक रूप से इस्तेमाल किया गया, जो एक वैकल्पिक रिटर्न प्रकार है।
जोर्ग डब्ल्यू मित्तग

3
@ JörgWMittag यदि आप किसी चीज़ के बारे में बात कर रहे हैं Option<T>, तो मुझे लगता है कि इससे C # 2.0 में उपयोग करने की विधि बहुत कठिन हो जाएगी, क्योंकि इसमें पैटर्न मिलान नहीं था।
svick

21

हैशटैब / शब्दकोशों के सामान्य सिद्धांतों पर यहाँ कुछ अच्छे उत्तर। लेकिन मुझे लगा कि मैं आपके कोड उदाहरण पर संपर्क करूंगा,

int x;
if (dict.TryGetValue("key", out x)) 
{
    DoSomethingWith(x);
}

C # 7 के अनुसार (जो मुझे लगता है कि लगभग दो साल पुराना है), जिसे सरल बनाया जा सकता है:

if (dict.TryGetValue("key", out var x))
{
    DoSomethingWith(x);
}

और निश्चित रूप से इसे एक पंक्ति में घटाया जा सकता है:

if (dict.TryGetValue("key", out var x)) DoSomethingWith(x);

जब आपके पास कुंजी मौजूद नहीं है, तो यह एक डिफ़ॉल्ट मान हो सकता है:

DoSomethingWith(dict.TryGetValue("key", out var x) ? x : defaultValue);

इसलिए आप यथोचित भाषा के अतिरिक्त उपयोग करके कॉम्पैक्ट रूप प्राप्त कर सकते हैं।


1
V7 सिंटैक्स पर अच्छा कॉल, अच्छा सा विकल्प है कि अतिरिक्त परिभाषा लाइन को काट दिया जाए जबकि var +1
ब्रायनएच

2
यह भी ध्यान दें कि यदि "key"मौजूद नहीं है, xतो प्रारंभ किया जाएगाdefault(TValue)
पीटर डुनिहो

जेनेरिक एक्सटेंशन के रूप में अच्छा हो सकता है, भी, जैसे"key".DoSomethingWithThis()
रॉस प्रेसर

मैं उन डिज़ाइनों को बहुत पसंद करता हूं जो getOrElse("key", defaultValue) नल ऑब्जेक्ट का उपयोग करते हैं फिर भी मेरा पसंदीदा पैटर्न है। इस तरह से काम करें और अगर आपको TryGetValueसही या गलत रिटर्न की परवाह नहीं है ।
candied_orange

1
मुझे ऐसा लगता है कि यह उत्तर एक अस्वीकरण का हकदार है जो कॉम्पैक्ट होने के लिए कॉम्पैक्ट कोड लिखना बुरा है। यह आपके कोड को पढ़ने में बहुत कठिन बना सकता है। इसके अतिरिक्त, अगर मैं सही ढंग से याद करता हूं, TryGetValueपरमाणु / धागा सुरक्षित नहीं है , तो आप आसानी से अस्तित्व के लिए एक चेक का प्रदर्शन कर सकते हैं और दूसरे को मूल्य पर हड़पने और संचालित करने के लिए
मेरी

12

यह न तो एक कोड गंध है और न ही एक एंटी-पैटर्न, जैसा कि आउट पैरामीटर के साथ TryGet- शैली के कार्यों का उपयोग करना मुहावरेदार है C #। हालाँकि, शब्दकोश के साथ काम करने के लिए C # में 3 विकल्प दिए गए हैं, इसलिए आपको यह सुनिश्चित करना चाहिए कि आप अपनी स्थिति के लिए सही उपयोग कर रहे हैं। मुझे लगता है कि मुझे पता है कि एक आउट पैरामीटर का उपयोग करने में समस्या होने की अफवाह कहां से आती है, इसलिए मैं इसे अंत में संभाल लूंगा।

C # शब्दकोश के साथ काम करते समय किन विशेषताओं का उपयोग करना है:

  1. यदि आप सुनिश्चित हैं कि कुंजी शब्दकोश में होगी, तो आइटम [TKey] संपत्ति का उपयोग करें
  2. यदि कुंजी आम तौर पर डिक्शनरी में होनी चाहिए, लेकिन यह खराब / दुर्लभ / समस्याग्रस्त है कि यह वहां नहीं है, तो आपको कोशिश करनी चाहिए ... कैच करें ताकि एक त्रुटि उठे और फिर आप इस त्रुटि को इनायत से संभालने की कोशिश कर सकें
  3. यदि आप सुनिश्चित नहीं हैं कि कुंजी शब्दकोश में होगी, तो आउट पैरामीटर के साथ TryGet का उपयोग करें

इस का औचित्य साबित करने के लिए, एक की जरूरत का उल्लेख केवल शब्दकोश TryGetValue के लिए दस्तावेज़ "टिप्पणियां" के अंतर्गत :

यह विधि ContainsKey विधि और आइटम [TKey] गुण की कार्यक्षमता को जोड़ती है।

...

TryGetValue विधि का उपयोग करें यदि आपका कोड अक्सर उन कुंजियों तक पहुंचने का प्रयास करता है जो शब्दकोश में नहीं हैं। आइटम [TKey] संपत्ति द्वारा फेंके गए KeyNotFoundException को पकड़ने की तुलना में इस विधि का उपयोग करना अधिक कुशल है।

यह विधि एक O (1) ऑपरेशन के पास जाती है।

संपूर्ण कारण TryGetValue मौजूद है, ContainsKey और Item [TKey] का उपयोग करने के लिए एक अधिक सुविधाजनक तरीके के रूप में कार्य करना है, जबकि शब्दकोश को दो बार खोजने से परहेज है - इसलिए यह दिखावा मौजूद नहीं है और दो चीजों को मैन्युअल रूप से करने के बजाय यह बहुत अजीब है चुनाव।

अभ्यास में, मैं शायद ही कभी कभी एक कच्चे शब्दकोश का इस्तेमाल किया है, इस सरल कहावत के कारण: सबसे सामान्य वर्ग / कंटेनर चुनें कि आप कार्यक्षमता की जरूरत है देता है । शब्दकोश को कुंजी (उदाहरण के लिए) के बजाय मूल्य द्वारा देखने के लिए डिज़ाइन नहीं किया गया था, इसलिए यदि आप चाहते हैं कि यह एक वैकल्पिक संरचना का उपयोग करने के लिए अधिक समझ में आता है। मुझे लगता है कि मैंने पिछले साल लंबे विकास परियोजना में एक बार शब्दकोश का उपयोग किया होगा, बस इसलिए कि शायद ही मैं उस काम के लिए सही उपकरण था जिसे मैं करने की कोशिश कर रहा था। शब्दकोश निश्चित रूप से सी # टूलबॉक्स का स्विस आर्मी चाकू नहीं है।

क्या मापदंडों के साथ गलत है?

CA1021: मापदंडों से बचें

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

मैं अनुमान लगा रहा हूं कि आपने कहां सुना है कि पैरामीटर एक विरोधी पैटर्न की तरह थे। सभी नियमों के साथ, आपको 'क्यों' को समझने के लिए करीब से पढ़ना चाहिए, और इस मामले में इस बात का भी स्पष्ट उल्लेख है कि कैसे नियम का उल्लंघन नहीं होता है :

सिस्टम पद्धति, जैसे कि System.Int32.TryParse, को लागू करने वाले तरीके इस उल्लंघन को नहीं बढ़ाते हैं।


मार्गदर्शन की पूरी सूची कुछ ऐसा है जो मैं चाहता हूं कि और लोग पढ़ें। जो लोग पालन करते हैं, उनके लिए यहां मूल है। docs.microsoft.com/en-us/visualstudio/code-quality/…
पीटर

10

सी # शब्दकोशों से कम से कम दो तरीके गायब हैं जो मेरी राय में अन्य भाषाओं में बहुत सारी स्थितियों में कोड को साफ करते हैं। पहला एक लौट रहा है Option, जो आपको स्काला में निम्नलिखित की तरह कोड लिखने देता है:

dict.get("key").map(doSomethingWith)

यदि कुंजी नहीं मिली तो दूसरा उपयोगकर्ता-निर्दिष्ट डिफ़ॉल्ट मान लौटा रहा है:

doSomethingWith(dict.getOrElse("key", "key not found"))

मुहावरों का उपयोग करने के लिए कुछ कहा जाना चाहिए, जब कोई भाषा Tryपैटर्न की तरह उपयुक्त होती है , लेकिन इसका मतलब यह नहीं है कि आपको केवल वही प्रदान करना है जो भाषा प्रदान करती है। हम प्रोग्रामर हैं। हमारी विशिष्ट स्थिति को समझने में आसान बनाने के लिए नए अमूर्त बनाना ठीक है, खासकर अगर यह बहुत सारे दोहराव को समाप्त करता है। यदि आपको अक्सर किसी चीज की आवश्यकता होती है, जैसे रिवर्स लुकअप या वैल्यू के माध्यम से पुनरावृत्ति करना, तो ऐसा करें। वह इंटरफ़ेस बनाएँ जो आप चाहते हैं।


मुझे दूसरा विकल्प पसंद है। शायद मुझे एक एक्सटेंशन विधि या दो :) लिखना होगा
एडम बी

2
प्लस साइड c # एक्सटेंशन के तरीकों का मतलब है कि आप इन्हें खुद लागू कर सकते हैं
jk।

5

यह कोड की 4 पंक्तियाँ अनिवार्य रूप से निम्नलिखित करने के लिए है: DoSomethingWith(dict["key"])

मैं इस बात से सहमत हूं कि यह एक अमानवीय है। एक तंत्र जिसे मैं इस मामले में उपयोग करना पसंद करता हूं, जहां मूल्य एक संरचनात्मक प्रकार है:

public static V? TryGetValue<K, V>(
      this Dictionary<K, V> dict, K key) where V : struct => 
  dict.TryGetValue(key, out V v)) ? new V?(v) : new V?();

अब हमारे पास TryGetValueउस रिटर्न का एक नया संस्करण है int?। फिर हम विस्तार के लिए एक समान चाल कर सकते हैं T?:

public static void DoIt<T>(
      this T? item, Action<T> action) where T : struct
{
  if (item != null) action(item.GetValueOrDefault());
}

और अब इसे एक साथ रखें:

dict.TryGetValue("key").DoIt(DoSomethingWith);

और हम एक एकल, स्पष्ट कथन के लिए नीचे हैं।

मैंने सुना है कि बाहर कीवर्ड का उपयोग करना एक विरोधी पैटर्न है क्योंकि यह फ़ंक्शन को उनके मापदंडों को म्यूट करता है।

मैं थोड़ा कम दृढ़ता से शब्द बनूंगा, और कहूंगा कि जब संभव हो तो म्यूटेशन से बचना एक अच्छा विचार है।

मुझे खुद को अक्सर एक "उलट" शब्दकोश की आवश्यकता होती है, जहां मैं कुंजी और मूल्यों को फ्लिप करता हूं।

फिर एक द्विदिश शब्दकोश को लागू करें या प्राप्त करें। वे लिखने के लिए सीधे हैं, या इंटरनेट पर बहुत सारे कार्यान्वयन उपलब्ध हैं। उदाहरण के लिए, यहाँ कार्यान्वयन का एक गुच्छा है:

/programming/268321/bidirectional-1-to-1-dictionary-in-c-sharp

इसी तरह, मैं अक्सर एक शब्दकोश में आइटम के माध्यम से पुनरावृति करना चाहता हूं और यह बेहतर करने के लिए खुद को सूचियों या मूल्यों को सूचियों आदि में परिवर्तित करना चाहता हूं।

ज़रूर, हम सब करते हैं।

मुझे लगता है कि शब्दकोशों का उपयोग करने का लगभग हमेशा एक बेहतर, अधिक सुरुचिपूर्ण तरीका है, लेकिन मैं नुकसान में हूं।

अपने आप से पूछें "मान लीजिए कि मेरे पास एक अन्य वर्ग था जो Dictionaryउस सटीक ऑपरेशन को लागू करता था जो मैं करना चाहता था? वह वर्ग कैसा दिखेगा?" फिर, एक बार जब आप उस प्रश्न का उत्तर दे देते हैं, तो उस कक्षा को लागू करें । आप एक कंप्यूटर प्रोग्रामर हैं। कंप्यूटर प्रोग्राम लिखकर अपनी समस्याओं को हल करें!


धन्यवाद। क्या आपको लगता है कि आप वास्तव में कुछ और व्याख्या कर सकते हैं कि एक्शन विधि वास्तव में क्या कर रही है? मैं कार्यों के लिए नया हूँ।
एडम बी

1
@ अदम एक क्रिया एक वस्तु है जो एक शून्य विधि को कॉल करने की क्षमता का प्रतिनिधित्व करती है। जैसा कि आप देखते हैं, कॉलर की तरफ हम एक शून्य विधि का नाम देते हैं, जिसकी पैरामीटर सूची कार्रवाई के सामान्य प्रकार के तर्कों से मेल खाती है। फोन करने वाले की ओर से किसी अन्य तरीके की तरह कार्रवाई की जाती है।
एरिक लिपर्ट

1
@ अदमबी: आप Action<T>बहुत समान होने के बारे में सोच सकते हैं interface IAction<T> { void Invoke(T t); }, लेकिन उस इंटरफ़ेस को "लागू" करने के बारे में बहुत उदार नियमों के साथ, और कैसे Invokeलागू किया जा सकता है। यदि आप अधिक जानना चाहते हैं, तो C # में "डेलिगेट्स" के बारे में जानें और फिर लैम्ब्डा एक्सप्रेशन के बारे में जानें।
एरिक लिपर्ट

ठीक है मुझे लगता है कि मैं समझ गया। तो कार्रवाई करते हैं कि आप DoIt () के पैरामीटर के रूप में एक विधि रखते हैं। और उस विधि को कहता है।
एडम बी

@ अदमब: बिल्कुल सही। यह "उच्च-क्रम के कार्यों के साथ कार्यात्मक प्रोग्रामिंग" का एक उदाहरण है। अधिकांश फ़ंक्शन डेटा को तर्क के रूप में लेते हैं; उच्च-क्रम के कार्य तर्कों के रूप में कार्य करते हैं और फिर उन कार्यों के साथ सामान करते हैं। जैसा कि आप अधिक C # सीखते हैं, आप देखेंगे कि LINQ पूरी तरह से उच्च-क्रम के कार्यों के साथ लागू किया गया है।
एरिक लिपर्ट

4

TryGetValue()निर्माण, यदि आप नहीं जानते कि क्या "कुंजी" शब्दकोश या नहीं के भीतर एक कुंजी के रूप में मौजूद है केवल आवश्यक है अन्यथा DoSomethingWith(dict["key"])पूरी तरह से वैध है।

एक "कम गंदे" दृष्टिकोण के ContainsKey()बजाय एक चेक के रूप में उपयोग किया जा सकता है ।


6
"एक कम गंदे" दृष्टिकोण के बजाय एक जांच के रूप में कॉन्टेंसेके () का उपयोग किया जा सकता है। " मैं असहमत हूं। जैसा कि उप-अपनाने वाला TryGetValueहै, कम से कम यह खाली मामले को संभालने के लिए भूलना मुश्किल बनाता है। आदर्श रूप में, मैं चाहता हूं कि यह एक वैकल्पिक वापसी होगी।
अलेक्जेंडर - मोनिका

1
ContainsKeyमल्टीथ्रेड अनुप्रयोगों के लिए दृष्टिकोण के साथ एक संभावित समस्या है , जो उपयोग के समय (TOCTOU) भेद्यता की जांच का समय है। क्या होगा यदि कुछ अन्य धागे कॉल को ContainsKeyऔर के बीच की कुंजी को हटा दें GetValue?
डेविड हैम्मन

2
@JAD ऑप्शंस कंपोज करते हैं। आपके पास एकOptional<Optional<T>>
अलेक्जेंडर - मोनिका

2
स्पष्ट है @DavidHammen, आप की आवश्यकता होगी TryGetValueपर ConcurrentDictionary। नियमित शब्दकोश सिंक्रनाइज़ नहीं किया जाएगा
अलेक्जेंडर - मोनिका

2
@JAD नहीं, (जावा का वैकल्पिक प्रकार चल रहा है, मुझे आरंभ न करें)। मैं और अधिक संक्षेप में बात कर रहा हूँ
अलेक्जेंडर - मोनिका

2

अन्य उत्तरों में महान बिंदु हैं, इसलिए मैं उन्हें यहाँ विश्राम नहीं दूंगा, लेकिन इसके बजाय मैं इस हिस्से पर ध्यान केंद्रित करूँगा, जो लगता है कि बड़े पैमाने पर अब तक अनदेखा किया गया है:

इसी तरह, मैं अक्सर एक शब्दकोश में आइटम के माध्यम से पुनरावृति करना चाहता हूं और यह बेहतर करने के लिए खुद को सूचियों या मूल्यों को सूचियों आदि में परिवर्तित करना चाहता हूं।

वास्तव में, यह एक शब्दकोश पर पुनरावृति करना बहुत आसान है, क्योंकि यह लागू होता है IEnumerable:

var dict = new Dictionary<int, string>();

foreach ( var item in dict ) {
    Console.WriteLine("{0} => {1}", item.Key, item.Value);
}

यदि आप Linq पसंद करते हैं, तो वह भी ठीक काम करता है:

dict.Select(x=>x.Value).WhateverElseYouWant();

सब सब में, मैं डिस्क्रिप्शन को एंटीपैटर्न नहीं मानता - वे विशिष्ट उपयोगों के साथ एक विशिष्ट उपकरण हैं।

इसके अलावा, और भी अधिक बारीकियों के लिए, बाहर की जाँच करें SortedDictionary(एक अधिक पूर्वानुमान प्रदर्शन के लिए आरबी पेड़ का उपयोग करता है) और SortedList(जो एक भ्रमित नाम का शब्दकोश भी है जो देखने की गति के लिए सम्मिलन गति का त्याग करता है, लेकिन अगर आप एक निश्चित, पूर्व के साथ बाहर घूर रहे हैं, तो चमकता है) हल किया हुआ)। मेरे पास एक ऐसा मामला है जहां परिमाण के क्रम में तेजी से निष्पादन के परिणामस्वरूप एक के Dictionaryसाथ प्रतिस्थापित किया गया है SortedDictionary(लेकिन यह दूसरे तरीके से भी हो सकता है)।


1

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

डिक्ट [कुंजी] बनाम ट्राईगेट के बारे में बहुत कुछ कहा गया है। क्या मैं एक बहुत का उपयोग करें KeyValuePair का उपयोग कर शब्दकोश में पुनरावृत्ति कर रहा हूँ। जाहिरा तौर पर यह एक कम ज्ञात निर्माण है।

एक शब्दकोश का मुख्य वरदान यह है कि यह अन्य संग्रहों की तुलना में वास्तव में तेज़ है क्योंकि वस्तुओं की संख्या बढ़ती है। यदि आपको यह जांचना है कि क्या कोई कुंजी मौजूद है या नहीं, तो आप खुद से पूछ सकते हैं कि क्या किसी शब्दकोश का उपयोग उचित है। एक ग्राहक के रूप में आपको आमतौर पर पता होना चाहिए कि आपने वहां क्या डाला है और इस तरह से क्या करना सुरक्षित होगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.