2009-12-04 12 views
5

क्या किसी ने "टाइप डिक्शनरी" के बारे में सुना है जो कि चाबियों के रूप में प्रकारों का उपयोग करता है और विरासत का समर्थन करता है?शब्दकोश टाइप करें?

अपने आवेदन में मैं, कार्यों के लिए प्रकार से एक शब्दकोश करना चाहते हैं एक तरह से इस तरह:

Dictionary<Type, Func<object, object>> Transformers; 

विचार है कि यह के आधार पर कुछ फैशन में एक वस्तु को बदलने के लिए इस्तेमाल किया जाएगा है इसके टाइप:

// Transform an object 'obj' 
object result = Transformers[obj.GetType()](obj) 

एक सामान्य शब्दकोश का नुकसान यह है कि इस प्रकार का नुकसान ठीक से मेल खाना चाहिए। इसलिए यदि मैंने IList < T> के लिए ट्रांसफ़ॉर्मर लिखा है, तो ट्रांसफॉर्मर्स डिक्शनरी में इसे डालने का कोई उपयोग नहीं है क्योंकि किसी ऑब्जेक्ट में IList < टी> (केवल टी [], सूची < टी> इत्यादि नहीं है) दूसरे शब्दों में , यदि ओबीजे एक सूची < टी> है, तो IList < टी के लिए ट्रांसफॉर्मर सामान्य शब्दकोश में लुकअप द्वारा नहीं मिलेगा।

मान लीजिए कि टाइप डिक्शनरी < टीवील्यू जैसी कोई चीज़ नहीं है, यदि मैं बहुत कठिन नहीं हूं तो मैं एक लिखने पर विचार कर सकता हूं। कोई विचार यह कैसे पूरा किया जा सकता है?

उत्तर

2

आपको custom comparer के साथ एक शब्दकोश का उपयोग करने में सक्षम होना चाहिए जो कुंजी की तुलना करने के लिए Type.IsAssignableFrom का उपयोग करता है।

अद्यतन: क्वर्टी ने बताया कि यह काम नहीं करता है क्योंकि आप किसी प्रकार, इसके इंटरफेस और पूर्वजों के वर्गों के आधार पर दोहराने योग्य हैश कोड गणना लागू नहीं कर सकते हैं। His answer टाइप, इंटरफेस और पूर्वजों के वर्गों के लिए बार-बार हैश टेबल लुक अप करके एक संभावित समाधान प्रदान करता है जब तक कि यह एक मैच न मिल जाए।

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

+1

यह काम नहीं करेगा। कौन सा हैश कोड IEqualityComparer कक्षा बी के लिए वापस आ जाएगा जो ए से प्राप्त होता है और आईए और आईबी लागू करता है? साथ ही, ध्यान रखें कि शब्दकोश 'सूची ', 'IList ' और 'ऑब्जेक्ट' के साथ-साथ 'कुंजी' के लिए कुंजी पकड़ने में सक्षम होना चाहिए। – Qwertie

+0

आप सही हैं, मैंने ऐसा नहीं सोचा था। –

+0

उस मामले में @ क्वर्टी, एक प्रकार के लिए शब्दकोश में कई मैचों में क्या होगा यदि आपका शब्दकोश वापस आ जाएगा? क्या यह सभी घटनाओं को वापस लेना चाहिए, केवल सबसे विशिष्ट, आदि? –

1

यह मेरे लिए होता है कि शब्दकोश सेटर एक साधारण शब्दकोश से अलग अर्थ विज्ञान नहीं है, इसलिए एक दृष्टिकोण विशेष देखने के साथ एक मानक शब्दकोश का उपयोग करना है:

public class TypeDictionary<TValue> : Dictionary<Type, TValue> 
{ 
    public new TValue this[Type key] 
    { 
     get { 
      TValue value; 
      if (TryGetValue(key, out value)) 
       return value; 
      throw new KeyNotFoundException("Not found: " + key.Name); 
     } 
    } 
    public new bool TryGetValue(Type key, out TValue value) 
    { 
     if (base.TryGetValue(key, out value)) 
      return true; 

     Type[] interfaces = key.GetInterfaces(); 
     for (int i = 0; i < interfaces.Length; i++) 
      if (base.TryGetValue(interfaces[i], out value)) 
       return true; 

     Type @base = key.BaseType; 
     if (@base != null && TryGetValue(@base, out value)) 
      return true; 

     return false; 
    } 
} 

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

मुझे नहीं पता कि इस शब्दकोश का प्रदर्शन कितना अच्छा है। अगर GetInterfaces() या बेसटाइप संपत्ति धीमी है, तो यह लुकअप प्रदर्शन को बहुत खराब कर देगा (जब भी सटीक प्रकार का अनुरोध आप शब्दकोश में नहीं है)।

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