2010-08-07 19 views
5

नाम के रूप में स्ट्रिंग का उपयोग करके गतिशील रूप से ऑब्जेक्ट बनाएं, क्या वर्ग नाम के रूप में स्ट्रिंग का उपयोग करके गतिशील रूप से ऑब्जेक्ट बनाने का कोई तरीका है?विजुअल बेसिक:

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

If c_name = "Button" then obj = new System.Windows.Forms.Button 
If c_name = "Form" then obj = new System.Windows.Forms.Form 
.... 

मैं बजाय आशा करती हूं कि यह सब मामले से निपटने को कम करने: यह इस तरह से करने के लिए, वहाँ सचमुच/तो है या मामलों अगर के सैकड़ों संदर्भित libs के भीतर सभी उपलब्ध वर्ग/वस्तु विकल्पों को संभालने के लिए हो सकता है एक पंक्ति: आईई ...

my_class_name = "whateverclass" 
obj = new System.Windows.Forms.my_class_name() 

पीएचपी में, यह इतना की तरह नियंत्रित किया जाता है ...

$my_class_name = "whateverclass"; 
$obj = new $my_class_name(); 

संपादित करें: कुछ उत्तर को देखते हुए , मुझे लगता है कि मैं अपने सिर पर रास्ते में हूं। मेरे द्वारा प्रबंधित था कि यह विधानसभा वर्ग के this CreateInstance विधि परिवर्तन का उपयोग करने के लिए काम कर रहा है, भले ही मैं this variation giving more options में अधिक रुचि हूँ, मानकों का निर्माण की आपूर्ति सहित ...

my_type_name = "System.Windows.Forms.Button" 
asmb_name = "System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" 
button1 = Reflection.Assembly.Load(asmb_name).CreateInstance(my_type_name) 

दूसरे शब्दों में, यह एक तरीका है करने के लिए ले जाता है यह, और कोई अंतर्निहित भाषा वाक्यविन्यास नहीं है? This Activator variation भी काम करता है जब पूर्ण असेंबली स्ट्रिंग और क्लास पथ का उपयोग किया जाता है। मुझे संदेह है कि CreateInstance में ऑब्जेक्ट्स का इलाज करने की पूर्ण क्षमता नहीं हो सकती है जैसे कि उन्हें सामान्य रूप से कहा जाता है, यानी obj = new System.Windows.Forms.Button। यही कारण है कि मैं बस CreateObject का उपयोग नहीं कर सकता। यदि कोई प्राकृतिक भाषा सुविधा नहीं है जो आपको स्ट्रिंग के लिए क्लास नाम को प्रतिस्थापित करने की इजाजत देती है, तो क्या किसी के पास CreateInstance का उपयोग करने से मुझे किस प्रकार की सीमाएं मिल सकती हैं?

इसके अलावा, बुनियादी सक्रियकर्ता के बीच भी अंतर है। क्रिएट इंस्टेंस (अनवर्रप के बाद) और असेंबली। क्रिएट इंस्टेंस तरीकों?

उत्तर

10

यह संभव है कि आप क्या चाहते/काम करने का परीक्षण होगा यह करना चाहिए; देखने के लिए शीर्ष पर टाइप टिप्पणी स्विच करें।

Imports System.Reflection 

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
    '   Dim fullyQualifiedClassName as String = "System.Windows.Forms.TextBox" 
    Dim fullyQualifiedClassName As String = "System.Windows.Forms.Button" 
    Dim o = fetchInstance(fullyQualifiedClassName) 
    ' sometime later where you can narrow down the type or interface... 
    Dim b = CType(o, Control) 
    b.Text = "test" 
    b.Top = 10 
    b.Left = 10 
    Controls.Add(b) 
End Sub 

Private Function fetchInstance(ByVal fullyQualifiedClassName As String) As Object 
    Dim nspc As String = fullyQualifiedClassName.Substring(0, fullyQualifiedClassName.LastIndexOf("."c)) 
    Dim o As Object = Nothing 
    Try 
     For Each ay In Assembly.GetExecutingAssembly().GetReferencedAssemblies() 
      If (ay.Name = nspc) Then 
       o = Assembly.Load(ay).CreateInstance(fullyQualifiedClassName) 
       Exit For 
      End If 
     Next 
    Catch 
    End Try 
    Return o 
End Function 
+1

अच्छा। 'फॉर्म 1_लोड()' वास्तव में COM के माध्यम से मेरे लिए एक और भाषा के माध्यम से संभाला जाएगा। रेखा 'ओ = असेंबली.लोड (एई)। क्रेते इंस्टेंस (पूरी तरह से क्वालिफाइड क्लासनाम)' इसे करना चाहिए। –

0

एक्टिवेटर पर एक नज़र डालें। क्रिएट इंस्टेंस (टाइप) विधि।

यदि आपका इनपुट एक वर्ग का नाम आप में सक्षम होना चाहिए है ऐसा करते हैं:

Dim obj As Object = Activator.CreateInstance(GetType("Name_Of_Your_Class")) 

आप GetType कॉल के साथ बेला करना होगा सुनिश्चित करें कि आप पर्याप्त जानकारी दे लेकिन ज्यादातर मामलों के लिए बनाने के लिए सिर्फ कक्षा का नाम काम करना चाहिए।

+0

मेरा मानना ​​है कि GetType() एक प्रकार की उम्मीद है, तो एक त्रुटि फेंक देते हैं। Type.Gettype ("System.Windows.Forms.Button") शून्य देता है। –

+0

मेरा वीबी थोड़ा जंगली है लेकिन यह निश्चित रूप से काम करना चाहिए। सुनिश्चित नहीं है कि आप शून्य क्यों प्राप्त कर रहे हैं, लेकिन यहां एक स्ट्रिंग पास करने के लिए GetType दस्तावेज़ नहीं है: http://msdn.microsoft.com/en-us/library/w3f99sx1.aspx – jwsample

+0

उदाहरण मूल रूप से मैं काफी कुछ था इसके बजाय टाइप प्रकार की गेट टाइप विधि को छोड़कर। मेरा मानना ​​है कि यह मुझे सिस्टम की खोज करने के लिए एक रास्ता तय करने के लिए अटक गया है। Windows.Forms.Button प्रकार। –

3

मुझे यकीन है कि सक्रियकर्ता को रिमोटिंग के लिए उपयोग किया जाता है। आप जो करना चाहते हैं वह है कन्स्ट्रक्टर प्राप्त करने के लिए प्रतिबिंब का उपयोग करें और इसे यहां एक उदाहरण दें http://www.eggheadcafe.com/articles/20050717.asp

संपादित करें: जब तक jwsample ने मुझे सही नहीं किया तब तक मुझे एक्टिवेटर के बारे में गुमराह किया गया।

मुझे लगता है कि आपकी समस्या यह है कि आपकी असेंबली वह है जो GetType बटन को खोजने और खोजने के लिए उपयोग कर रही है। आपको इसे सही असेंबली से कॉल करने की आवश्यकता है।

यह

Dim asm As System.Reflection.Assembly = System.Reflection.Assembly.LoadWithPartialName("System.Windows.Forms") 


Dim obj As Object = Activator.CreateInstance(asm.GetType("System.Windows.Forms.Button")) 
+1

वाह, आपने उस पोस्ट के साथ अपनी पोस्ट की पूरी सामग्री बदल दी है और अब मेरी पिछली टिप्पणी पागल आदमी की छिद्रों की तरह दिखती है। – jwsample

+0

इसके बारे में क्षमा करें। मैंने इसे वापस रख दिया। –

+1

अच्छी लीड। नाइटपिक से नफरत है, लेकिन एक्टिवेटर के साथ। क्रिएटइंस्टेंस, क्योंकि यह एक हैंडल देता है, इसके लिए यह आवश्यक है कि आप ऑब्जेक्ट बनाने के लिए हैंडल अनवर्र विधि को कॉल करें। साथ ही, विधानसभा.LoadWithPartialName विधि http://msdn.microsoft.com/en-us/library/system.reflection.assembly.loadwithpartialname.aspx के अनुसार अप्रचलित है। शर्मिंदा, क्योंकि मैं वास्तव में संस्करणों, संस्कृतियों और चाबियों को खोजने की कोशिश करने के आसपास गड़बड़ करने के बजाय इसका उपयोग कर सकता था। –

0

यहाँ एक बहुत आसान तरीका मैं जबकि इंटरनेट के माध्यम से तलाशी पाया है है:

dynamicControl = Activator.CreateInstance(Type.GetType("MYASSEMBLYNAME." + controlNameString)) 
संबंधित मुद्दे