2009-02-23 10 views
37

का ऑब्जेक्ट बनाएं मेरे पास मेरे डेटाबेस में एक तालिका है जिसका उपयोग मैं अपने एप्लिकेशन में रिश्तों को प्रबंधित करने के लिए करता हूं। यह प्रकृति में बहुत बुनियादी है - पैरेंट टाइप, पैरेंट आईडी, चाइल्ड टाइप, childId ... सभी चींटियों के रूप में। मैंने पहले यह सेटअप किया है, लेकिन मैंने इसे स्विच/केस सेटअप के साथ किया था जब मेरे पास 6 अलग-अलग टेबल थे जिन्हें मैं लिंक करने का प्रयास कर रहा था। अब मेरे पास 30 टेबल हैं जो मैं इसे करने की कोशिश कर रहा हूं और मैं अपने स्विच कमांड में 30 केस प्रविष्टियों को लिखने के बिना ऐसा करने में सक्षम होना चाहता हूं।गतिशील रूप से <Type>

क्या कोई तरीका है कि मैं एक स्ट्रिंग का उपयोग कर .NET क्लास का संदर्भ दे सकता हूं? मैं जानता हूँ कि यह मान्य नहीं है (क्योंकि मैं इस के कई रूप की कोशिश की है):

Type t = Type.GetType("WebCore.Models.Page"); 
object page = new t(); 

मुझे पता है कि एक वस्तु का प्रकार प्राप्त करने के लिए, लेकिन मैं कैसे प्रयोग करते हैं कि मक्खी पर एक नया बनाने के लिए आपत्ति?

उत्तर

49

इस कड़ी की मदद करनी चाहिए:

http://msdn.microsoft.com/en-us/library/system.activator.createinstance(VS.71).aspx

Activator.CreateInstance निर्दिष्ट प्रकार का एक उदाहरण का निर्माण करेगा।

आप लपेट सकता है कि इस तरह एक सामान्य विधि में:

public T GetInstance<T>(string type) 
{ 
    return (T)Activator.CreateInstance(Type.GetType(type)); 
} 
+2

यह काम नहीं करेगा अगर इस प्रकार की असेंबली पहले से ही ऐपडोमेन में लोड नहीं हुई है। –

+3

भी उस विधि को कॉल करने के लिए, ओपी को संकलन समय पर प्रकार तक पहुंच होनी चाहिए - मूल प्रश्न पूछा गया कि एक स्ट्रिंग से निष्पादन समय पर एक उदाहरण कैसे बनाया जाए। –

+0

मैं केवल प्रश्न में दिए गए उदाहरण पर अपना उत्तर दे रहा हूं। –

9

आप Activator.CreateInstance उपयोग करना चाहते हैं।

यह ऐसे काम करता का एक उदाहरण है:

using System; 
using System.Runtime.Remoting; 

class Program 
{ 
    static void Main() 
    { 
     ObjectHandle o = Activator.CreateInstance("mscorlib.dll", "System.Int32"); 

     Int32 i = (Int32)o.Unwrap(); 
    } 
} 
11

प्रकार फोन करने वाले से जाना जाता है, तो वहाँ Activator.CreateInstance का उपयोग करने से एक बेहतर, तेज़ तरीका है: आप के बजाय पर एक सामान्य बाधा उपयोग कर सकते हैं विधि जो निर्दिष्ट करती है कि इसमें डिफ़ॉल्ट पैरामीटर रहित कन्स्ट्रक्टर है।

ऐसा करने से यह टाइप-सुरक्षित है और प्रतिबिंब की आवश्यकता नहीं है।

T CreateType<T>() where T : new() 
{ 
    return new T(); 
} 
+6

इसे स्रोत कोड स्तर पर प्रतिबिंब की आवश्यकता नहीं है - यह उत्पन्नकर्ता आईएल में सक्रियकर्ता। क्रिएटइंस्टेंस का उपयोग करता है। –

+1

प्रतिबिंब आवश्यक है क्योंकि ओपी टाइप की पहचान करने के लिए स्ट्रिंग का उपयोग करके निर्दिष्ट किया गया है। –

0

मान लें कि आप निम्न प्रकार है:

public class Counter<T> 
{ 
    public T Value { get; set; } 
} 

और प्रकार की विधानसभा योग्य नाम है, तो आप निम्नलिखित तरीके से यह निर्माण कर सकते हैं:

string typeName = typeof(Counter<>).AssemblyQualifiedName; 
Type t = Type.GetType(typeName); 

Counter<int> counter = 
    (Counter<int>)Activator.CreateInstance(
    t.MakeGenericType(typeof(int))); 

counter.Value++; 
Console.WriteLine(counter.Value); 
8
public static T GetInstance<T>(params object[] args) 
{ 
    return (T)Activator.CreateInstance(typeof(T), args); 
} 

मैं एक्टिवेटर का उपयोग करूंगा। क्रिएट इंस्टेंस() कास्टिंग के बजाय, एक्टिवेटर एच के रूप में जेनेरिक के लिए एक निर्माता के रूप में।

1

यहां एक ऐसा कार्य है जिसे मैंने लिखा है कि क्लोन प्रतिबिंब का उपयोग करते हुए टाइप टी का रिकॉर्ड है। यह एक बहुत ही सरल कार्यान्वयन है, मैं जटिल प्रकार आदि

public static T Clone<T>(T original) 
    { 
     T newObject = (T)Activator.CreateInstance(original.GetType()); 

     foreach (var prop in original.GetType().GetProperties()) 
     { 
      prop.SetValue(newObject, prop.GetValue(original)); 
     } 

     return newObject; 
    } 

संभाल नहीं था मुझे आशा है कि यह किसी की मदद कर सकते हैं।

असफ़

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