5

मैं एक विस्तार विधि है कि IDictionary<K, S<V>> संग्रह/अनुक्रम में किसी भी प्रकार के आयोजन में परिवर्तित कर देंगे लिखने के लिए कोशिश कर रहा हूँ (S<V>) ILookup<K, V> जिसमें अधिक उचित डेटा संरचना है उन मामलों में। इसका मतलब यह है मैं अलग S प्रकार और इंटरफेस पर काम करने के लिए अपने एक्सटेंशन चाहते हैं:एकल विस्तार विधि <कश्मीर, IEnumerable/IList/ICollection <V>>

  • IDictionary<K, IEnumerable<V>>
  • IDictionary<K, ICollection<V>>
  • IDictionary<K, List<V>>

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

क्या मैं कोशिश की है है:

public static ILookup<TKey, TValue>ToLookup<TKey, TCollection, TValue>(
    this IDictionary<TKey, TCollection> dictionary) 
     where TCollection : IEnumerable<TValue> 

लेकिन यह पैरामीटर सूची में कोई TValue है, तो अनुमान टाइप यह पता लगाने में असमर्थ है - मैं "विधि ToLookup के लिए प्रकार तर्क से नहीं लगाया जा सकता उपयोगितायें"।

क्या कोई मौका है कि यह विधि के लिए नकली TValue -typed पैरामीटर जोड़ने से किसी अन्य तरीके से काम कर सकता है?

उम्मीद के उपयोग के उदाहरण

मैं सब से ऊपर आशा है कि संभव हो सकता है और अपने एक विस्तार विधि के लिए एक कॉल में परिणाम के लिए कॉल:

var dictOfIEnumerables = new Dictionary<int, IEnumerable<int>>(); 
var lookupFromIEnumerables = dictOfIEnumerables.ToLookup(); 

var dictOfICollections = new Dictionary<int, ICollection<int>>(); 
var lookupFromICollections = dictOfICollections.ToLookup(); 

var dictOfLists = new Dictionary<int, List<int>>(); 
var lookupFromLists = dictOfLists.ToLookup(); 
+0

जब आप इसका उपयोग करते हैं, तो जेनरिक – Mgetz

+0

@Mgetz के लिए स्पष्ट रूप से प्रकारों को निर्दिष्ट करने का प्रयास करें - मुझे लगता है कि यह बिल्कुल सही है कि नोथरडेव से बचने की कोशिश करता है - या तो स्पष्ट रूप से प्रकारों को निर्दिष्ट करने या प्रकारों को मजबूर करने के लिए नकली तर्कों को निर्दिष्ट करना। अपेक्षित उपयोग का नमूना शायद चीजों को साफ़ करेगा। –

+0

हां, जैसा कि मैंने उल्लेख किया है, मैं अपनी नौकरी करने के लिए टाइप अनुमान चाहता हूं। प्रश्न के लिए अपेक्षित उपयोग उदाहरण जोड़ देंगे। – NOtherDev

उत्तर

1

क्योंकि सभी संग्रह IEnumerable<T> लागू है, हम बस यह बजाय का उपयोग कर सकते TCollection प्रकार पैरामीटर का। दुर्भाग्यवश प्रकार अनुमान इस बारे में नहीं जानता है।इस कोड को मैंने लिखा है:

public static ILookup<TKey, TValue> ToLookup<TKey, TValue> 
     (this IDictionary<TKey, IEnumerable<TValue>> dict) 
{ 
    return dict.SelectMany(p => p.Value.Select 
     (v => new KeyValuePair<TKey, TValue>(p.Key, v))) 
     .ToLookup(p => p.Key, p => p.Value); 
} 

वहाँ प्रकार निष्कर्ष काम करने का कोई रास्ता नहीं हो रहा है, लेकिन अगर आप शब्दकोश डाली इस विधि से काम करेगा:

((IDictionary<int, IEnumerable<int>>)dictOfLists).ToLookup() 

इसके अलावा, आप सूचियों में जोड़ सकते हैं IENumerables के एक शब्दकोश के लिए और जब आपको उनकी आवश्यकता हो तो उन्हें वापस डालें।

0

परीक्षण के बिट मेरे द्वारा की गई से, यहां मेरे परिणाम हैं।

यदि मैं dictOfIEnumerables.ToLookup( टाइप करता हूं, तो मुझे 4 अधिभारित विधियां दिखाई देती हैं।
enter image description here

हालांकि, अगर मैं dictOfIEnumerables.ToLookup< टाइप करें, मैं सभी 5 अतिभारित तरीकों को देखते हैं। enter image description here

ऐसा प्रतीत होता है कि टाइप अनुमान अनुमानित नहीं है, क्योंकि ट्यूनूकअप() के बीच नाम टकराव/रिज़ॉल्यूशन टकराव की वजह से IENumerable पर परिभाषित किया गया है। स्पष्ट रूप से, कोण ब्रैकेट के बिना, यह IENumerable पर परिभाषित विधियों का समाधान कर रहा है, क्योंकि टीसीओलेक्शन प्रतिबंधित है। हो सकता है कि स्टैक ओवरव्लो पर कोई व्यक्ति जो मुझसे ज्यादा चालाक है, आपको समझा सकता है कि यह किस तरह से काम करता है।

हालांकि, निर्दिष्ट प्रकारों का उपयोग करके, वास्तव में, मेरी मशीन पर सही तरीके से काम करता है। enter image description here

+0

खैर, वास्तव में समस्या नाम टक्कर के कारण नहीं है, समस्या 'ToLookup2' के साथ बनी हुई है। मुझे पता है कि मैं स्पष्ट रूप से तर्क निर्दिष्ट कर सकता हूं, लेकिन यह वही है जो मैं टालने की कोशिश कर रहा हूं। ऐसा लगता है कि मुझे प्रत्येक इंटरफ़ेस के लिए विधि को डुप्लिकेट करने की आवश्यकता है ... – NOtherDev

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