c# - Instantiating IDictionary<K, IEnumerable<V>> -
मेरे पास हस्ताक्षर के साथ एक विधि है
सार्वजनिक void Foo (IDictionary & lt; string, IEnumerable & lt ; स्ट्रिंग & gt; & gt; डेटा) {}
और
निजी शब्दकोश & lt; स्ट्रिंग, हाशसेट & lt; स्ट्रिंग & gt; & gt; MyInput = नया शब्दकोश & lt; स्ट्रिंग, हैशसेट & lt; स्ट्रिंग & gt; & gt; () {};
रेखा
फू (myInput);
संकलक त्रुटि उत्पन्न करती है:
<तर्क 1:
सिस्टम से परिवर्तित नहीं किया जा सकता है। Collections.Generic.Dictionary & lt; स्ट्रिंग, System.Collections.Generic HashSet & lt; स्ट्रिंग & gt; & gt;
से
System.Collections.Generic.IDictionary & lt; स्ट्रिंग, System.Collections.Generic.IEnumerable & lt; स्ट्रिंग & gt; & gt;
शब्दकोश & lt; K, V & gt;
लागू करता है IDictionary & lt; K, V & gt;
और HashSet & lt; T & gt;
लागू करता है IEnumerable & lt; T & gt; < / कोड>। - रूपांतरण करने में असमर्थ क्यों कंपाइलर है?
- मैं उस डेटा का एक उदाहरण कैसे बना सकता हूं जिसे मैं
Foo ? नोट
यदि मैं हस्ताक्षर को
सार्वजनिक void Foo (IDictionary & lt; string, HashSet & lt; string & gt; & Gt; डेटा)
संकलन सफल होता है हालांकि, मुझे किसी भी ज्ञान की ज़रूरत नहीं है कि HashSet & lt; T & gt;
जैसे किसी ठोस प्रकार में पारित किया जा रहा है। कोई भी IEnumerable & lt; T & gt;
होगा।
< P> UPDATE निम्न संकलित:
सार्वजनिक void Foo (IDictionary & lt; स्ट्रिंग, IEnumerable & lt; स्ट्रिंग & gt; & gt; डेटा) {सूची & lt; स्ट्रिंग & gt; आइटम = नई सूची & lt; स्ट्रिंग & gt; () {"foo", "bar", "baz"}; डेटा। जोड़ें ("कुंजी", आइटम); HashSet & LT; स्ट्रिंग & gt; Item2 = नया हैशसेट & lt; स्ट्रिंग & gt; () {"quu"}; डेटा। जोड़ें ("कुंजी 2", आइटम 2); }
इतना स्पष्ट रूप से डेटा
मिश्रित-प्रकार के मान स्वीकार कर सकते हैं जो सभी IEnumerable & lt; T & gt;
इसका कारण यह काम नहीं है, इसके कारण प्रतिबंधों की वजह से है इसे समझाने का सबसे अच्छा तरीका यह है कि इस को विफल करने के कारणों का एक उदाहरण दिखाना है।
मान लें कि Foo
मान्य हस्ताक्षर है, प्रकार प्रणाली का वादा करता है कि निम्नलिखित काम करता है:
var myInput = नया शब्दकोश & lt; स्ट्रिंग, हैशसेट & lt; स्ट्रिंग & gt; & gt; (); // `फू 'फू (मायइनपूट) के लिए मान्य हस्ताक्षर मानते हुए; // 'myInput` के प्रकार के अनुसार निम्न जरूरी काम हाशसेट & lt; स्ट्रिंग & gt; आइटम = myInput ["foo"]; item.Add ( "baz");
यही है बिल्कुल को काम करना है तो कुछ भी फ़ू
को यह सुनिश्चित करने की आवश्यकता है कि यह अभी भी काम करता है।
तो एक पल के लिए उपरोक्त उपेक्षा करना, मान लें कि valid Foo
:
सार्वजनिक void Foo (IDictionary & lt; स्ट्रिंग, IEnumerable & lt; स्ट्रिंग & gt; & gt; डेटा) {सूची & lt; स्ट्रिंग & gt; आइटम = नई सूची & lt; स्ट्रिंग & gt; () {"foo", "bar"}; डेटा। जोड़ें ("फू", आइटम); }
क्योंकि उपकरण IEnumerable & lt; स्ट्रिंग & gt;
s पूरी तरह से कार्य करता है उस शब्दकोश में सूची ऑब्जेक्ट को जोड़कर IEnumerable & lt; string & gt;
फिर से: ऊपर इसके हस्ताक्षर के लिए Foo
का एक वैध कार्यान्वयन है।
हालांकि, अगर हम अब दोनों कोड खंडों को जोड़ते हैं, तो वह अलग हो जाता है: ऑब्जेक्ट कुंजी इसलिए यहां कुछ मनमाना और अंतर्निहित नियम बनाने के बजाय, यह केवल अनुमति नहीं है टाइप सिस्टम केवल एक असंगत पैरामीटर के साथ Foo "
एक हैशसेट नहीं है; स्ट्रिंग & gt;
लेकिन सूची & lt; स्ट्रिंग & gt;
तो हॅशसेट पर & lt; स्ट्रिंग & gt; आइटम = myInput ["foo"]
असफल हो जायेगा लेकिन यहां एक संघर्ष है! प्रकार प्रणाली को यह सुनिश्चित करना चाहिए कि असाइनमेंट कोई काम नहीं करता है जो Foo
के अंदर होता है; लेकिन फ़ू का कार्यान्वयन इसके हस्ताक्षर के लिए पूरी तरह से मान्य है।
Foo
की ऐसी कॉल को रोकता है। और नहीं, क्योंकि IDictionary अपरिवर्तनीय है, इस प्रतिबंध के आसपास काम करना संभव नहीं है।
Comments
Post a Comment