2010-11-04 16 views
33

साथ एक सामान्य विधि कॉलिंग कहते हैं कि मैं निम्नलिखित वर्गोंएक गतिशील प्रकार

public class Animal { .... } 

public class Duck : Animal { ... } 

public class Cow : Animal { ... } 

public class Creator 
{ 
    public List<T> CreateAnimals<T>(int numAnimals) 
    { 
     Type type = typeof(T); 
     List<T> returnList = new List<T>(); 
     //Use reflection to populate list and return 
    } 
} 

अब कुछ कोड में बाद में मैं क्या पशु बनाने के लिए पढ़ने के लिए करना चाहते हैं देता है।

Creator creator = new Creator(); 
string animalType = //read from a file what animal (duck, cow) to create 
Type type = Type.GetType(animalType); 
List<animalType> animals = creator.CreateAnimals<type>(5); 

अब समस्या यह है कि अंतिम पंक्ति मान्य नहीं है। क्या ऐसा करने के लिए कुछ शानदार तरीका है?

+2

जेनिक्स वास्तव में यहां जाने का तरीका नहीं है, आपको केवल सूची सूची बनाना चाहिए और व्युत्पन्न कक्षाएं बनाने के लिए एक्टिवेटर का उपयोग करना चाहिए। – Doggett

उत्तर

18

वास्तव में नहीं। आपको मूल रूप से प्रतिबिंब का उपयोग करने की आवश्यकता है। जेनिक्स वास्तव में निष्पादन समय पर ज्ञात प्रकारों के बजाय स्थिर टाइपिंग का लक्ष्य रखते हैं।

प्रतिबिंब का उपयोग करने के लिए, आप विधि परिभाषा प्राप्त करने के लिए Type.GetMethod का उपयोग करेंगे, फिर MethodInfo.MakeGenericMethod(type) पर कॉल करें, फिर उसे किसी अन्य विधि की तरह आमंत्रित करें।

46

मैं के बारे में सुरुचिपूर्ण पता नहीं है, लेकिन जिस तरह से यह करने के लिए है:

typeof(Creator) 
    .GetMethod("CreateAnimals") 
    .MakeGenericMethod(type) 
    .Invoke(creator, new object[] { 5 }); 
+2

यद्यपि आप इसे 'सूची ' या 'सूची ' आदि के रूप में डालने में सक्षम नहीं होंगे, जब तक कि आप संकलित समय पर पहले से ही नहीं जानते हैं, जो आप नहीं करते हैं। सबसे अच्छा आप कर सकते हैं 'IList' पर डाला जाता है। – LukeH

+0

@LukeH, ठीक है, अच्छा बिंदु। –

+0

यह बहुत बदसूरत है, लेकिन यह सही जवाब – tofutim

1

यह करने के लिए सुझाव दिए गए हैं MakeGenericType() और MakeGenericMethod()। एक बार जब आप प्रकार के साथ गतिशील हो जाते हैं, तो आप वास्तव में स्थिर टाइपिंग पर वापस नहीं जा सकते हैं। आप क्या कर सकते हैं Activator.CreateInstance(typeof(List<>).MakeGenericType(type)) का उपयोग करके गतिशील रूप से सूची बनाएं और फिर गतिशील रूप से समान प्रतिबिंबित विधियों का उपयोग करके जेनेरिक विधि को कॉल करें।

3

इस प्रयास करें:

public List<T> CreateAnimals<T>(int numAnimals) where T : Animal 
{ 
    Type type = typeof(T); 
    List<T> returnList = new List<T>(); 
    //Use reflection to populate list and return 
} 

यह सुनिश्चित करें कि CreateAnimals के लिए अनुमति दी प्रकार पशु से विरासत बनाना चाहिए। तो उम्मीद है कि, यह List<animalType> animals = creator.CreateAnimals<type>(5);

+0

है जो वास्तव में मदद नहीं करता है अगर ओपी स्ट्रिंग से कौन से पशु प्रकार को बनाने के लिए पढ़ना चाहता है। –

0
List<animalType> animals = 
creator.CreateAnimals<type>(5); 

अपने उदाहरण से ऊपर लाइन में के साथ एक समस्या नहीं होगी, animalType और type समय चर, नहीं प्रकार चलाए जा रहे हैं, तो यह निश्चित रूप से बकवास है। एक सामान्य संस्करण केवल, समझ में आता है अगर तुम संकलन समय पर प्रकार जानते हैं, उदा .:

List<Animal> animals = 
    creator.CreateAnimals<Cow>(5); 

आप तदनुसार प्रकार में रोके होगा जहां। यदि प्रकार ज्ञात नहीं हैं, तो आपको प्रतिबिंब पर पूरी तरह भरोसा करना होगा ...

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