2010-02-11 11 views
48

से तत्काल वर्ग में मेरा एक सार वर्ग है और मैं इसे उस वर्ग में शामिल करना चाहता हूं जो इसे विस्तारित करता है।सी # स्ट्रिंग

मेरे पास बाल वर्ग का नाम स्ट्रिंग के रूप में है।

इस के अलावा ...

String childClassString; 
MyAbstractClass myObject; 

if (childClassString = "myExtenedObjectA") 
    myObject = new ExtenedObjectA(); 
if (childClassString = "myExtenedObjectB") 
    myObject = new ExtenedObjectB(); 

मैं यह कैसे कर सकते हैं? असल में मैं यहां बयानों से कैसे छुटकारा पा सकता हूं?

+1

तुम क्यों एक स्ट्रिंग के साथ अपने वर्ग instanciate करने की आवश्यकता है:

मैं काम करने के लिए क्या मिला इस प्रकार है? आपके मामले के आधार पर, "क्लीनर" समाधान हो सकते हैं, खासकर यदि आप प्रतिबिंब का उपयोग करने में अनिच्छुक नहीं हैं। –

+1

@SylvestreEquy लेकिन शायद किसी के एल्स मामलों में, यह सिर्फ समाधान है ... SO पर प्रश्न न केवल उनसे पूछते हैं जो उनसे पूछते हैं। –

उत्तर

90

एक्टिवेटर देखें। क्रिएट इंस्टेंस()।

myObject = (MyAbstractClass)Activator.CreateInstance("AssemblyName", "TypeName"); 

या

var type = Type.GetType("MyFullyQualifiedTypeName"); 
var myObject = (MyAbstractClass)Activator.CreateInstance(type); 
+6

एक आकर्षण की तरह काम किया। अगर किसी को पूरी तरह से योग्य नाम प्राप्त करने में समस्याएं आती हैं, तो कोड का यह टुकड़ा सहायक 'स्ट्रिंग टाइपएक्स = टाइपफ़ोफ़ (क्लासनाम) सहायक होता है .अनुक्रम योग्यता नाम; –

+0

भले ही 'टाइपटाइप' प्रलेखन 'टाइपनाम' पैरामीटर के लिए प्रलेखन "प्रकार का असेंबली-योग्य नाम" कहता है, आपको वास्तव में असेंबली नाम शामिल करने की आवश्यकता नहीं है। यदि प्रकार कॉलिंग असेंबली में है, तो केवल नामस्थान-योग्य प्रकार का नाम पर्याप्त है। –

18

मेरा मानना ​​है कि यह काम करना चाहिए:

myObject = (MyAbstractClass)Activator.CreateInstance(null, childClassString); 

null वर्तमान क्रियान्वित विधानसभा के लिए पहले पैरामीटर चूक में। MSDN

संपादित करें: अधिक संदर्भ के लिए मैं कुछ उत्तर यहाँ लागू करने, क्योंकि मैं एक अलग विधानसभा से एक वस्तु का दृष्टांत करने की कोशिश कर रहा था कुछ परेशानी (लेकिन एक ही समाधान में) था MyAbstractClass

1

को कास्ट करने के लिए भूल गया था। तो मैंने सोचा कि मैं जो काम करता हूं उसे पोस्ट करूंगा।

सबसे पहले, Activator.CreateInstance विधि में कई अधिभार हैं। यदि आप केवल Activator.CreateInstance(Type.GetType("MyObj")) पर कॉल करते हैं, तो यह मानता है कि ऑब्जेक्ट वर्तमान असेंबली में परिभाषित किया गया है, और यह MyObj देता है।

यदि आप इसे यहां उत्तर में अनुशंसित के रूप में कॉल करते हैं: Activator.CreateInstance(string AssemblyName, string FullyQualifiedObjectName), तो इसके बजाय यह ObjectHandle देता है, और आपको अपनी ऑब्जेक्ट प्राप्त करने के लिए Unwrap() पर कॉल करने की आवश्यकता है। यह ओवरलोड एक अलग असेंबली (बीटीडब्ल्यू) में परिभाषित विधि को कॉल करने का प्रयास करते समय उपयोगी होता है, आप वर्तमान असेंबली में इस अधिभार का उपयोग कर सकते हैं, बस AssemblyName पैरामीटर नल छोड़ दें)।

अब, मैंने पाया है कि typeof(ParentNamespace.ChildNamespace.MyObject).AssemblyQualifiedName का उपयोग करने के लिए ऊपर दिए गए सुझाव AssemblyName के लिए वास्तव में मुझे त्रुटियां मिलीं, और मैं इसे काम नहीं कर सका। मुझे System.IO.FileLoadException मिल जाएगा (फ़ाइल या असेंबली लोड नहीं हो सका ...)।

var container = Activator.CreateInstance(@"AssemblyName",@"ParentNamespace.ChildNamespace.MyObject"); 
MyObject obj = (MyObject)container.Unwrap(); 
obj.DoStuff(); 
संबंधित मुद्दे