2008-09-26 17 views
58

के डिफ़ॉल्ट कन्स्ट्रक्टर प्राप्त करने का सबसे प्रभावी तरीका सिस्टम के किसी भी प्रकार के डिफॉल्ट कन्स्ट्रक्टर (यानी किसी पैरामीटर के साथ इंस्टेंस कन्स्ट्रक्टर) प्राप्त करने का सबसे प्रभावी तरीका क्या है। टाइप करें?टाइप

मैं नीचे दिए गए कोड की रेखाओं के साथ कुछ सोच रहा था लेकिन ऐसा लगता है कि ऐसा करने के लिए एक आसान और अधिक प्रभावी तरीका होना चाहिए।

Type type = typeof(FooBar) 
BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; 
type.GetConstructors(flags) 
    .Where(constructor => constructor.GetParameters().Length == 0) 
    .First(); 

उत्तर

112
type.GetConstructor(Type.EmptyTypes) 
+6

स्थिर सदस्य जिन्हें आप कभी नहीं देखते ... यह शानदार है। –

+1

निजी सदस्यों को भी देखा नहीं जाता है।मान लीजिए कि आपको केवल सार्वजनिक की जरूरत है तो यह सबसे सरल प्रतीत होता है। हालांकि यह सबसे तेज़ है? मैं अभी पता लगाने के लिए एक परीक्षण पर काम कर रहा हूं। –

+6

कुछ उपाय इस उपाय को मापने के बाद MeasureIt (http://msdn.microsoft.com/en-us/magazine/cc500596.aspx) का उपयोग करके मेरे दृष्टिकोण बनाते हैं। यह दृष्टिकोण सभी सरल मामलों में तेज़ है और फिर भी यह मुश्किल से धीमा है। तो यह दोनों सबसे सरल और सबसे तेज़ है। धन्यवाद! –

28

आप वास्तव में जरूरत ConstructorInfo वस्तु, तो Curt Hagenlocher's answer देखें।

दूसरी ओर, यदि आप वास्तव में सिर्फ एक System.Type से रन-टाइम में एक वस्तु बनाने के लिए कोशिश कर रहे हैं, System.Activator.CreateInstance देखते हैं - यह सिर्फ भविष्य-रहित नहीं है (उत्प्रेरक ConstructorInfo.Invoke की तुलना में अधिक विवरण संभालती है), यह भी है बहुत कम बदसूरत।

+2

संभावित रूप से खतरनाक सलाह के साथ काम नहीं कर रहा है, क्योंकि कुछ ऑब्जेक्ट्स में डिफॉल्ट कन्स्ट्रक्टर नहीं हैं (स्ट्रिंग एक है)। तो यदि आप बस इस विचित्र-कॉल को कॉल करते हैं, तो आप एक MissingMethod अपवाद के साथ समाप्त हो सकते हैं। इस विधि को कॉल करने से पहले मुझे वास्तव में एक डिफ़ॉल्ट कन्स्ट्रक्टर की जांच करनी होगी। – cunningdave

+0

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

-2

आप FormatterServices.GetUninitializedObject (प्रकार) की कोशिश करना चाहते हैं इस एक, Activator.CreateInstance से

हालांकि बेहतर है, इस विधि वस्तु निर्माता फोन नहीं करता है, इसलिए यदि आप प्रारंभिक मान वहाँ सेट कर रहे हैं इस इस बात के लिए MSDN चेक http://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatterservices.getuninitializedobject.aspx

एक और तरीका यहां http://www.ozcandegirmenci.com/post/2008/02/Create-object-instances-Faster-than-Reflection.aspx

है काम नहीं करेगा लेकिन यह एक निष्पक्ष अगर विफल रहता है टी parametrize कंस्ट्रक्टर्स है

आशा इस मदद करता है

0

आप केवल वर्ग का दृष्टांत के लिए डिफ़ॉल्ट निर्माता प्राप्त करना चाहते हैं, और एक कार्य करने के लिए एक सामान्य प्रकार पैरामीटर के रूप में प्रकार हो रही है, तो आप निम्न कर सकते हैं:

T NewItUp<T>() where T : new() 
{ 
    return new T(); 
} 
+3

या सिर्फ 'नया टी() 'lol –

1

यदि आपके पास सामान्य प्रकार पैरामीटर है, तो जेफ ब्रिजमैन का जवाब सबसे अच्छा है। यदि आपके पास केवल उस प्रकार का ऑब्जेक्ट है जिसका आप निर्माण करना चाहते हैं, तो आप Activator.CreateInstance(Type) का उपयोग कर सकते हैं जैसे कि एलेक्स लाइमैन ने सुझाव दिया था, लेकिन मुझे बताया गया है कि यह धीमा है (मैंने इसे व्यक्तिगत रूप से प्रोफाइल नहीं किया है)।

using System; 
using System.Linq.Expressions; 

public static class TypeHelper 
{ 
    public static Func<object> CreateDefaultConstructor(Type type) 
    { 
     NewExpression newExp = Expression.New(type); 

     // Create a new lambda expression with the NewExpression as the body. 
     var lambda = Expression.Lambda<Func<object>>(newExp); 

     // Compile our new lambda expression. 
     return lambda.Compile(); 
    } 
} 

बस फोन प्रतिनिधि आपको लौटा:

हालांकि, अगर आप अपने आप को लगता है इन वस्तुओं बहुत बार निर्माण, वहाँ एक और अधिक सुवक्ता दृष्टिकोण गतिशील संकलित Linq भाव का उपयोग कर रहा है। आपको इस प्रतिनिधि को कैश करना चाहिए, क्योंकि लिंक अभिव्यक्तियों को लगातार पुन: सम्मिलित करना महंगा हो सकता है, लेकिन यदि आप प्रतिनिधि को कैश करते हैं और इसे हर बार पुन: उपयोग करते हैं, तो यह बहुत तेज़ हो सकता है! मैं व्यक्तिगत रूप से टाइप करके अनुक्रमित एक स्थिर लुकअप शब्दकोश का उपयोग करता हूं। यह फ़ंक्शन काम में आता है जब आप धारावाहिक वस्तुओं से निपट रहे हैं जहां आप केवल प्रकार की जानकारी जान सकते हैं।

नोट: यदि यह प्रकार रचनात्मक नहीं है या डिफ़ॉल्ट डिज़ाइनर नहीं है तो यह असफल हो सकता है!

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