2010-09-22 10 views
11

मुझे एक सामान्य प्रकार मिला है:यह कोड "जेनेरिक टाइप परिभाषा की धैर्य" के बारे में क्यों शिकायत करेगा?

class DictionaryComparer<TKey, TValue> : IEqualityComparer<IDictionary<TKey, TValue>> 

और एक कारखाना विधि जो किसी दिए गए शब्दकोश प्रकार के लिए इस वर्ग का एक उदाहरण बनायेगी (चाहिए)।

 private static IEqualityComparer<T> CreateDictionaryComparer<T>() 
    { 
     Type def = typeof(DictionaryComparer<,>); 
     Debug.Assert(typeof(T).IsGenericType); 
     Debug.Assert(typeof(T).GetGenericArguments().Length == 2); 

     Type t = def.MakeGenericType(typeof(T).GetGenericArguments()); 

     return (IEqualityComparer<T>)Activator.CreateInstance(t); 
    } 

सभी अपर्याप्त सामानों को दूर करना - यहां तक ​​कि यह कोड भी एक ही अपवाद फेंकता है।

private static object CreateDictionaryComparer() 
{ 
    Type def = typeof(DictionaryComparer<,>); 

    Type t = def.MakeGenericType(new Type[] { typeof(String), typeof(object) }); 

    return Activator.CreateInstance(t); 
} 

आवेषण पास करते हैं इसलिए मुझे पता है कि T सामान्य है और इसमें दो सामान्य तर्क हैं। Xzx46 के साथ लाइन हालांकि इसके साथ समाप्त होती है:

प्रदान किए गए सामान्य तर्कों की संख्या जेनेरिक प्रकार परिभाषा की समानता के बराबर नहीं है।

पैरामीटर नाम: तात्कालिकता

मैंने अतीत में इस तरह की चीज की है और मेरे जीवन के लिए यह पता नहीं लगा सकता कि यह इस मामले में क्यों काम नहीं कर रहा है। (प्लस मुझे Google arity था)।

+0

आप 'टी' के रूप में 'createDictionaryComparer' के रूप में क्या गुजर रहे हैं? मैंने 'CreateDictionaryComparer >()' को पारित करने का प्रयास किया है और यह मेरे लिए ठीक काम करता है (मोनो सी # कंपाइलर संस्करण 1.9.1.0 का उपयोग करके)। –

+0

मेरे पास शब्दकोशकंपर एक आंतरिक वर्ग के रूप में था जो स्वयं सामान्य है। सोचो कि काम को खो रहा था। – dkackman

+0

जिज्ञासा से बाहर, क्या आप पूर्ण (असफल) नमूना प्रदान कर सकते हैं ताकि मैं इसे अपने कंपाइलर पर आज़मा सकूं? –

उत्तर

13

यह पता लगाया।

मेरे पास DictionaryComparer एक आंतरिक कक्षा के रूप में घोषित किया गया था। मैं केवल यह मान सकता हूं कि MakeGenericTypeQuery<T>.DictionaryComparer<string,object> बनाना चाहता था और T प्रदान नहीं किया गया था।

कोड प्रत्येक के लिए एक आंतरिक डेटा संरचना और एक application.These डेटा संरचनाओं द्वारा उपयोग में हर प्रकार प्रकार वस्तु कहा जाता है बनाता असफल

class Program 
{ 
    static void Main(string[] args) 
    { 
     var q = new Query<int>(); 
     q.CreateError(); 
    } 
} 

public class Query<TSource> 
{ 
    public Query() 
    {  
    } 

    public object CreateError() 
    { 
     Type def = typeof(DictionaryComparer<,>); 

     Type t = def.MakeGenericType(new Type[] { typeof(String), typeof(object) }); 

     return Activator.CreateInstance(t); 
    } 

    class DictionaryComparer<TKey, TValue> : IEqualityComparer<IDictionary<TKey, TValue>> 
    { 
     public DictionaryComparer() 
     { 
     } 

     public bool Equals(IDictionary<TKey, TValue> x, IDictionary<TKey, TValue> y) 
     { 
      if (x.Count != y.Count) 
       return false; 

      return GetHashCode(x) == GetHashCode(y); 
     } 

     public int GetHashCode(IDictionary<TKey, TValue> obj) 
     { 
      int hash = 0; 
      unchecked 
      { 
       foreach (KeyValuePair<TKey, TValue> pair in obj) 
       { 
        int key = pair.Key.GetHashCode(); 
        int value = pair.Value != null ? pair.Value.GetHashCode() : 0; 
        hash ^= key^value; 
       } 
      } 
      return hash; 
     } 
    } 
} 
+0

जिज्ञासा से बाहर, क्या आप पूर्ण (असफल) नमूना प्रदान कर सकते हैं ताकि मैं इसे अपने कंपाइलर पर आज़मा सकूं? –

+0

लेमे देखें कि क्या मैं एक संगत उदाहरण – dkackman

+0

पर असंबद्ध सामान को पट्टी कर सकता हूं धन्यवाद! 'DictionaryComparer ' जेनेरिक कंटेनर क्लास के बाहर 'क्वेरी ' समस्या को हल करता है। मैंने प्रयोग किया और आप 'शब्दकोशकंपर <टेके, टीवीएयू>' घोंसला कर सकते हैं, बस एक और सामान्य वर्ग के अंदर नहीं। यह भी सुनिश्चित करना चाहता था कि मेरा कंपाइलर और रनटाइम पर्यावरण आपके जैसा ही व्यवहार कर रहा हो। –

1

CLR। जेनेरिक टाइप पैरामीटर वाले एक प्रकार को ओपन टाइप कहा जाता है, और सीएलआर एक खुले प्रकार के किसी भी इंस्टेंस को (सीएलआर कैसे बनाया जा सकता है) के समान उदाहरण की अनुमति नहीं देता है।

बदलें t = def.MakeGenericType टाइप करें (नया प्रकार [] {टाइपोफ (स्ट्रिंग), टाइपऑफ (ऑब्जेक्ट)});

प्रकार टी पर = def.MakeGenericType (नए प्रकार [] {typeof (TSource), typeof (स्ट्रिंग), typeof (वस्तु)});

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