एक स्ट्रिंग से एक वर्ग का एक उदाहरण बनाएँ


218

क्या इस तथ्य के आधार पर एक कक्षा का एक उदाहरण बनाने का एक तरीका है जो मैं रनटाइम के दौरान कक्षा का नाम जानता हूं। मूल रूप से मैं एक स्ट्रिंग में कक्षा का नाम होगा।


आपको लगता है कि आप जिस समाधान को लागू करना चाहते हैं, उसका वर्णन किया है, लेकिन उस समस्या को हल करने की कोशिश नहीं कर रहे हैं। शायद आप एक्स्टेंसिबिलिटी के साथ कुछ करने की कोशिश कर रहे हैं, जिस स्थिति में मैं आपको प्रबंधित एक्स्टेंसिबिलिटी फ्रेमवर्क की जांच करने का सुझाव देता हूं ।
Jay Bazuzi

जवाबों:


159

Activator.CreateInstance पद्धति पर एक नज़र डालें ।


15
महान उदाहरणों से संबंधित: stackoverflow.com/questions/493490/…
John S.

साथ ही यह पोस्ट प्रासंगिक भी होगी, क्योंकि आपके प्रकार को खोजने की आवश्यकता है: stackoverflow.com/questions/1825147/…
ब्रैड पार्क्स


4
उदाहरण के लिए:var driver = (OpenQA.Selenium.IWebDriver)Activator.CreateInstance("WebDriver", "OpenQA.Selenium.Firefox.FirefoxDriver").Unwrap();
Endy Tjahjono

2
महत्वपूर्ण नोट यहां: .Unwrap () रीमोटिंग हैंडल को प्राप्त करने के लिए ताकि आप वास्तव में कलाकारों को कर सकें। @Endy - धन्यवाद
रोजर Willcocks

77

यह बहुत आसान है। मान लें कि आपका क्लासनाम है Carऔर नेमस्पेस है Vehicles, तो उस पैरामीटर को पास करें, Vehicles.Carजो टाइप का ऑब्जेक्ट देता है Car। इस तरह आप गतिशील रूप से किसी भी वर्ग का कोई भी उदाहरण बना सकते हैं।

public object GetInstance(string strFullyQualifiedName)
{         
     Type t = Type.GetType(strFullyQualifiedName); 
     return  Activator.CreateInstance(t);         
}

यदि आपका पूरी तरह से योग्य नाम (अर्थात, Vehicles.Carइस मामले में) किसी अन्य विधानसभा में है, तो Type.GetTypeयह शून्य होगा। ऐसे मामलों में, आपके पास सभी असेंबली के माध्यम से लूप हैं और पाते हैं Type। उसके लिए आप नीचे दिए गए कोड का उपयोग कर सकते हैं

public object GetInstance(string strFullyQualifiedName)
{
     Type type = Type.GetType(strFullyQualifiedName);
     if (type != null)
         return Activator.CreateInstance(type);
     foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
     {
         type = asm.GetType(strFullyQualifiedName);
         if (type != null)
             return Activator.CreateInstance(type);
     }
     return null;
 }

अब अगर आप एक पैरामीटर बनाने वाले को कॉल करना चाहते हैं तो निम्न कार्य करें

Activator.CreateInstance(t,17); // Incase you are calling a constructor of int type

के बजाय

Activator.CreateInstance(t);

बिना कास्टिंग के इसका उपयोग कैसे करें और दिए गए स्ट्रिंग से कास्ट कैसे करें ??
TaW

1
@TaW - एक वर्ग उदाहरण का उपयोग करने के लिए आपको कुछ ज्ञान की आवश्यकता होगी कि वह क्या करने जा रहा है - अन्यथा आप इसका उपयोग नहीं कर पाएंगे। इसके लिए सबसे आम उपयोग मामला कुछ इंटरफ़ेस के लिए होगा जो आपको एक पूर्वनिर्धारित अनुबंध देता है। (यह तब तक होता है जब तक आप dynamicकोड का उपयोग नहीं करते हैं - देखें stackoverflow.com/a/2690661/904521 )
तोमर कागन

1
यह के नाम पर चर के प्रकार के सांकेतिक शब्दों में बदलना नहीं है, उदाहरण के लिए:। वहाँ उपसर्ग की आवश्यकता नहीं है strFullyQualifiedNameके साथ str, fullyQualifiedNameकाम करेगा।
मेहदी देहनागी

कीवर्ड strका उपयोग चर के लिए नामकरण सम्मेलन के एक भाग के रूप में किया जाता है। कुछ संगठन और परियोजनाएं इसका पालन करने के लिए जोर देते हैं, इसलिए मैंने इसका उपयोग किया। यदि आपने कुछ विशेष ऑर्गनाइज़ेशंस / प्रोजेक्ट्स में काम किया होता, तो आपको यह पता होता। जैसा कि आपने कहा कि इसके बिना strभी यह काम करेगा :) @MehdiDehagani
Sarath Avanavu

1
मैं जानता हूं कि नामकरण सम्मेलनों के बारे में जानने के लिए किसी भी संगठन में काम करने की कोई आवश्यकता नहीं है, हालांकि इस सम्मेलन को हंगेरियन नोटेशन के रूप में जाना जाता है और यह वहां से निकले बुरे और पदावनत नामकरण सम्मेलनों में से एक है। विशेष रूप से सी # के लिए
मेहदी देहनागी

55

मैंने इस विधि का सफलतापूर्वक उपयोग किया है:

System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(string className)

आपको अपने इच्छित ऑब्जेक्ट प्रकार को दिए गए ऑब्जेक्ट को डालना होगा।


9
मैं एक ऐसे परिदृश्य की कल्पना करने की कोशिश कर रहा हूं, जहां कक्षा के नाम के माध्यम से ऑब्जेक्ट का निर्माण किया जा रहा है और फिर इसे उस प्रकार से कास्टिंग किया जा रहा है जिससे किसी भी तरह का कोई मतलब हो।
मुसइनेसिस

13
मुझे पता है तुम्हारा क्या मतलब है। यह बेमानी लगता है। यदि आप वर्ग का नाम जानते हैं, तो आपको गतिशील स्ट्रिंग की आवश्यकता क्यों है? एक स्थिति यह हो सकती है कि आपका आधार वर्ग के लिए कास्टिंग और स्ट्रिंग उस आधार वर्ग के वंशजों का प्रतिनिधित्व करता है।
रे ली

4
यदि बेस क्लास जाना जाता है, तो आप बेस क्लास या इसके इंटरफ़ेस का उपयोग कर सकते हैं, क्योंकि बिना प्रतिबिंब के वंशज को पास करने का तर्क।
गार्ट क्लैबोर्न

3
उपयोगी परिदृश्य: आपको केवल क्रमबद्ध इंटरफ़ेस या किसी अन्य सामान्य इंटरफ़ेस की आवश्यकता है। आप इसे कक्षा में नहीं
डालेंगे

2
दिए गए तार से कलाकारों को कैसे करना है ??
TaW

23

संभवतः मेरा प्रश्न अधिक विशिष्ट होना चाहिए था। मैं वास्तव में स्ट्रिंग के लिए एक बेस क्लास जानता हूं, इसलिए इसे इसके द्वारा हल किया गया है:

ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));

Activator.CreateInstance वर्ग में एक ही चीज़ को विभिन्न तरीकों से प्राप्त करने के विभिन्न तरीके हैं। मैं इसे एक वस्तु में डाल सकता था लेकिन उपरोक्त मेरी स्थिति के लिए सबसे अधिक उपयोग है।


4
प्रश्न अनुभाग में जवाब देने के बजाय, मैं आपको अपना प्रश्न संपादित करने और परिवर्तनों पर ध्यान देने का सुझाव दूंगा। आपको इसे करने के लिए अधिक / बेहतर उत्तर मिलेंगे।
जेसन जैक्सन

आपके लिए काम करने वाले कोड की विशिष्ट लाइन पोस्ट करने के लिए धन्यवाद। सभी CreateInstance ओवरलोड और विभिन्न प्रकार के जेनरेट करने के माध्यम से सॉर्ट करने में मुझे बहुत समय लग रहा था, जो आपने मुझे बचाया।
एथेल इवांस

4

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

फिर, यदि आपकी सभी कक्षाएं जो इस तरह से उत्पन्न होती हैं, उस इंटरफ़ेस को लागू करती हैं, तो आप बस इंटरफ़ेस प्रकार के रूप में डाल सकते हैं और परिणामी वस्तु के साथ काम कर सकते हैं।


4

समाधान में किसी अन्य परियोजना से एक वर्ग का एक उदाहरण बनाने के लिए, आप किसी भी वर्ग (उदाहरण के लिए BaseEntity) के नाम से संकेतित विधानसभा प्राप्त कर सकते हैं और एक नया उदाहरण बना सकते हैं:

  var newClass = System.Reflection.Assembly.GetAssembly(typeof(BaseEntity)).CreateInstance("MyProject.Entities.User");

3

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


-11
ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));

आप इस तरह से एक कोड क्यों लिखना चाहते हैं? यदि आपके पास एक क्लास 'ReportClass' उपलब्ध है, तो आप इसे सीधे नीचे दिखा सकते हैं।

ReportClass report = new ReportClass();

कोड ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));का उपयोग तब किया जाता है जब आपके पास आवश्यक वर्ग उपलब्ध नहीं होता है, लेकिन आप एक विधि को गतिशील रूप से इंस्टेंट करना और या करना चाहते हैं।

मेरा मतलब है कि यह तब उपयोगी है जब यू असेंबली जानता है लेकिन कोड लिखते समय आपके पास कक्षा ReportClassउपलब्ध नहीं है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.