2009-10-30 11 views
26

क्या ऑब्जेक्ट बनाने के दो तरीकों के बीच कोई अंतर है।एक्टिवेटर। क्रिएटइंस्टेंस <T> बनाम नया

Student s1 = Activator.CreateInstance<Student>(); 
Student s1 = new Student(); 
  • वहाँ जिस तरह से निर्माता कहा जाता है में या स्मृति आरंभ में कोई अंतर है?
  • मेरी समझ के अनुसार, पहली विधि पूरी तरह से अनावश्यक दिखती है। यदि प्रोग्रामर डिज़ाइन समय के दौरान डेटा प्रकार जानता है, तो वह दूसरी विधि का उपयोग करेगा।
+0

संबंधित: http://stackoverflow.com/questions/6582259/fast-creation-of-objects-instead-of-activator-createinstancetype, http://stackoverflow.com/questions/6069661/does-system-activator -createinstancet-have-performance-issues-big-enough-to-di – nawfal

उत्तर

12

"Activator.CreateInstance" विधि का यह अधिभार के साथ सामान्य CreateInstance<T>() का उपयोग कर प्रकार पैरामीटर द्वारा निर्दिष्ट प्रकार के इन्स्टेन्शियशन लागू करने के लिए compilers द्वारा किया जाता है भ्रमित किया है जेनरिक।

आप निम्न विधि है कहते हैं:

public static T Factory<T>() where T: new() 
{ 
    return new T(); 
} 

संकलक में परिवर्तित कर देंगे "वापस नई टी();" "CreateInstance" कॉल करने के लिए।

सामान्यतः, अनुप्रयोग कोड में CreateInstance के लिए कोई उपयोग नहीं है, क्योंकि प्रकार संकलन समय पर जाना जाना चाहिए। यदि प्रकार संकलन समय पर जाना जाता है, तो सामान्य तत्काल वाक्यविन्यास का उपयोग किया जा सकता है (सी # में नया ऑपरेटर, विजुअल बेसिक में नया, सी ++ में जीसीएनयू)।

अधिक जानकारी: http://msdn.microsoft.com/en-us/library/0hcyx2kd.aspx

+10

संकलन समय पर अज्ञात होने के लिए यह बहुत आम है। अनुबंध (इंटरफ़ेस) और कार्यान्वयन को अलग करते समय यह बहुत उपयोगी होता है। – Thorarin

+0

'CreateInstance' के बिना deserialization कोड लिखना बहुत कठिन होगा! – Gabe

+0

मैं अंतिम पैराग्राफ को बस गलत समझाऊंगा। कॉन्फ़िगरेशन में टाइपनाम को रखना आम बात है और इसे तुरंत चालू करने की आवश्यकता है। मुझे लगता है कि आप विशेष रूप से जेनेरिक अधिभार (प्रश्न में उपयोग किए गए) का जिक्र कर रहे हैं जिसके लिए संकलन समय पर ठोस प्रकार की आवश्यकता होगी। –

3

नहीं, Activator.CreateInstance<T> बस कवर के तहत डिफ़ॉल्ट कन्स्ट्रक्टर को कॉल करता है। आपके उदाहरणों के बीच एकमात्र अंतर CreateInstance<T> पर एक अतिरिक्त विधि कॉल है।

Activator.CreateInstance<T> से:

प्रकार निर्दिष्ट सामान्य प्रकार पैरामीटर द्वारा नामित की आवृत्ति बनाता है, parameterless निर्माता का उपयोग कर।

4

नया कॉल करना बेहतर प्रदर्शन-आधारित CreateInstance शायद प्रतिबिंब का उपयोग करता है जो धीमा है।
यदि आप डिज़ाइन समय के दौरान प्रकार जानते हैं - नए का उपयोग करें, भले ही दो कॉल बिल्कुल समान हों (वे नहीं हैं!) आपके कोड को अधिक जटिल क्यों करें?

एक्टिवेटर का उपयोग करें। केवल सुधार करें जब आप डिज़ाइन समय में टी के प्रकार को नहीं जानते हैं और आपको प्रकार के रन-टाइम रिज़ॉल्यूशन की आवश्यकता है।

+0

हां, यह प्रतिबिंब का उपयोग करता है और इस प्रकार, 'एक्टिवेटर' के बजाय 'नया टी() 'पसंदीदा होना चाहिए। क्रिएटइंस्टेंस ()' ([स्रोत] (http : //typedescriptor.net/browse/members/246503-System.Activator.CreateInstance [टी]()))। – Shimmy

5

मैं Activator.CreateInstance() अनावश्यक नहीं कहूंगा।

यदि आप इस प्रकार को जानते हैं, तो हाँ, आप बस new का उपयोग करेंगे। हालांकि, परिस्थितियों में प्लगइन ढांचे से अज्ञात प्रकारों की गतिशील लोडिंग की आवश्यकता होती है या जहां स्ट्रिंग से टाइप को पार्स किया जाता है (कहें, कहें, एक सेटिंग-फाइल), यह बेहद उपयोगी है।

और दोनों के बीच के अंतर के रूप में प्रश्न का उत्तर देने के लिए, हूड के नीचे new T() और Activator.CreateInstance<T>() पर कॉल करने के बीच कोई वास्तविक अंतर नहीं है, जैसा कि एंड्रयू हरे द्वारा पहले ही बताया गया है।

संपादित करें: कोई बात नहीं, मैं नहीं तो और अधिक सामान्य रूप से इस्तेमाल किया CreateInstance(Type type)

3

एक बड़ा अंतर ये है कि

Student s1 = new Student(); 

अगर वहाँ Student पर कोई डिफ़ॉल्ट निर्माता है संकलन नहीं होगा, जबकि

Student s1 = Activator.CreateInstance<Student>(); 

संकलन जाएगा, भले ही Student करता है एक डिफ़ॉल्ट कन्स्ट्रक्टर नहीं है। (यह संकलित होगा, और आपको प्रोग्राम चलाने देगा, लेकिन यदि कोई मिलान करने वाला कन्स्ट्रक्टर नहीं है तो आपको अपवाद मिलेगा, जबकि कन्स्ट्रक्टर कॉल भी संकलित नहीं होगा अगर कन्स्ट्रक्टर मौजूद नहीं है।)

इसी प्रकार, CreateInstance कॉल कक्षा का एक निहित उपयोग है, इसलिए, उदाहरण के लिए, रिशेर्पर को यह नहीं पता होगा कि आप इसे तुरंत चालू कर रहे हैं, और आपको बता सकते हैं कि कक्षा कभी भी तत्काल नहीं है।

अन्य उत्तर में उल्लेख किया है, CreateInstance कॉल भी एक सामान्य प्रकार पैरामीटर के उपयोग के लिए अनुमति देता है:

T s1 = Activator.CreateInstance<T>(); 

हालांकि आप शायद बेहतर होगा एक new प्रकार बाधा का उपयोग कर, क्योंकि यह आप संकलन देना होगा होगा समय पर आश्वासन है कि वास्तव में एक कन्स्ट्रक्टर कहा जाता है।

Activator.CreateInstance(Type, ...) अधिभार अधिक उपयोगी हैं, हालांकि।

+0

क्या आप निश्चित हैं? यदि कोई डिफॉल्ट नहीं है तो कौन सा कन्स्ट्रक्टर कॉल करेगा? उस कन्स्ट्रक्टर को यह कौन सा पैरामीटर होगा? –

+0

@ZarShardan यह एक अपवाद फेंक देगा। मेरा मुद्दा यह था कि यह अभी भी संकलित होगा; यानी: आपको एक कंपाइलर त्रुटि के बजाय रनटाइम त्रुटि मिल जाएगी। (कंपाइलर त्रुटियां प्राथमिक हैं।) –

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

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