मैं एक सामान्य वर्ग में एक सामान्य विधि के लिए रनटाइम (टाइपबिल्डर के माध्यम से) पर उत्पन्न एक प्रकार को पास करना चाहता हूं। मैं इसे ऑब्जेक्ट के रूप में पास नहीं कर सकता क्योंकि विभिन्न गुणों को देखने के लिए प्रतिबिंब का उपयोग किया जाता है।

जैसा कि मैं समझता हूं, यह नहीं किया जा सकता क्योंकि जेनेरिक रन-टाइम के बजाय संकलन-समय पर लागू होते हैं।

मुझे पता है कि मैं एक विधि बदल सकता हूँ जैसे

public T Read()
{
     T data = new T()
     ...
     return data;
}

कुछ ऐसा होना

public object Read(Type newType)
{
     object data =  Activator.CreateInstance(newType);  
     ...
     return data;
}

लेकिन यह स्पष्ट रूप से जेनेरिक के सभी फायदे खो देता है जब प्रकार ज्ञात होता है, इसलिए मैं शायद दोनों विधियों के साथ समाप्त हो जाऊंगा, दुर्भाग्य से इसका मतलब कुछ अन्य सहायक कार्यों को डुप्लिकेट करना भी है।

क्या इस मुद्दे को हल करने का कोई बेहतर तरीका है?

इस विशेष परियोजना को 3.5 ढांचे के तहत काम करने की जरूरत है, लेकिन अगर यह 3.5 में संभव नहीं है, लेकिन 4.0 से कम है, तो मुझे यह जानने में कोई दिक्कत नहीं होगी।

1
sgmoore 2 अप्रैल 2011, 15:46

1 उत्तर

सबसे बढ़िया उत्तर

मान लें कि Read() class Reader<T> where T : new() का सदस्य है, तो आप इस तरह के सामान्य संस्करण को कॉल कर सकते हैं (संभवतः GetMethod() के एक और अधिभार का उपयोग करके यदि आपके पास Read नाम के साथ एक से अधिक विधियाँ हैं। उस प्रकार पर):

Type readerType = typeof(Reader<>).MakeGenericType(generatedType);
object result = readerType
                  .GetMethod("Read")
                  .Invoke(Activator.CreateInstance(readerType), new object[0]);

इस तरह, आपको Read() के अंदर जेनरिक का लाभ मिलता है, लेकिन बाहर नहीं। आप जो करना चाहते हैं उसके आधार पर, जेनरिक के बजाय इंटरफेस का उपयोग करना बेहतर होगा। new() बाधा का अनुकरण प्रत्येक उत्पन्न प्रकार के लिए फ़ैक्टरी प्रकार उत्पन्न करके किया जा सकता है, निम्नलिखित (गैर-जेनरेट) इंटरफेस को लागू करने वाले प्रकार:

interface IWhatever { … }

interface IWhateverFactory
{
    IWhatever Create();
}
4
svick 2 अप्रैल 2011, 17:27