2011-01-13 16 views
78

मैं यह जांचना चाहता हूं कि रनटाइम पर ज्ञात एक प्रकार पैरामीटर रहित कन्स्ट्रक्टर प्रदान करता है या नहीं। Type कक्षा ने कुछ भी वादा नहीं किया, इसलिए मुझे लगता है कि मुझे प्रतिबिंब का उपयोग करना है?मैं कैसे जांचूं कि कोई प्रकार पैरामीटर रहित कन्स्ट्रक्टर प्रदान करता है या नहीं?

+0

मुझे लगता है कि यह सही है – kenny

+2

Sidenote: पैरामीटर रहित रचनाकारों के लिए एक सामान्य बाधा है। – CodesInChaos

+1

सवाल यह है कि टाइप ** केवल ** पैरामीटर रहित कन्स्ट्रक्टर प्रदान करता है या यदि यह बिल्कुल एक प्रदान करता है? बाद में – BrokenGlass

उत्तर

132

Type वर्ग प्रतिबिंब है। आप कर सकते हैं:

Type theType = myobject.GetType(); // if you have an instance 
// or 
Type theType = typeof(MyObject); // if you know the type 

var constructor = theType.GetConstructor(Type.EmptyTypes); 

यदि पैरामीटर रहित कन्स्ट्रक्टर मौजूद नहीं है तो यह शून्य हो जाएगा।


तो आप निजी निर्माताओं को खोजने के लिए चाहते हैं, थोड़ा लंबा का उपयोग करें:

var constructor = theType.GetConstructor(
    BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, 
    null, Type.EmptyTypes, null); 

मूल्य प्रकार हैं, जिनमें aren't allowed to have a default constructor के लिए एक चेतावनी है। आप जांच सकते हैं कि आपके पास Type.IsValueType प्रॉपर्टी का उपयोग करके कोई मान प्रकार है, और Activator.CreateInstance(Type) का उपयोग करके उदाहरण बनाएं;

+2

यह निजी ctors fyi –

+2

नहीं मिलेगा यह मूल्य प्रकारों के लिए भी काम नहीं करेगा। – leppie

+2

उपरोक्त टिप्पणियों को संबोधित किया गया। –

12

हां, आपको प्रतिबिंब का उपयोग करना होगा।

var t = x.GetType(); 
var c = t.GetConstructor(new Type[0]); 
if (c != null) ... 
6

यह काम करना चाहिए:: लेकिन आप पहले से ही है कि जब आप GetType()

कुछ की तरह इस्तेमाल करते हैं

myClass.GetType().GetConstructors() 
        .All(c=>c.GetParameters().Length == 0) 
+1

मेरा मतलब क्या नहीं था, लेकिन कृपया हटाएं - यह एक संबंधित मुद्दा और अच्छी जानकारी है। – mafu

1

हां, आपको प्रतिबिंब का उपयोग करना होगा।

object myObject = new MyType(); 
Type type = myObject.GetType(); 
ConstructorInfo conInfo = type.GetConstructor(new Type[0]); 
3

अपनी स्थिति पर निर्भर करता है, तो आप भी एक सामान्य प्रकार प्रतिबंध इस्तेमाल कर सकते हैं:

public void DoSomethingWith<T>(T myObject) where T:new() {...} 

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

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

+0

वास्तव में, स्थैतिक और गतिशील आमंत्रण की भूमि को ब्रिज करने के लिए एक बहुत उपयोगी पैटर्न है: एक स्थैतिक जेनेरिक कैशिंग कक्षा [उदा। 'समानता कॉम्पैयर। डीफॉल्ट ']। किसी दिए गए प्रकार 'टी' के लिए, किसी को केवल एक ऑब्जेक्ट बनाने के लिए प्रतिबिंब का उपयोग करना होगा जिसका आवृत्ति प्रकार किसी भी आवश्यक बाधाओं के लिए अर्हता प्राप्त करने के लिए स्थिर रूप से जाना जाता है, और उस क्षेत्र में इसका संदर्भ संग्रहीत करता है जो किसी भी बाधा को लागू नहीं करता है एक कॉलर आपूर्ति करने में सक्षम नहीं हो सकता है। – supercat

10
type.GetConstructor(Type.EmptyTypes) != null 

struct एस के लिए विफल हो जाएगा। बेहतर यह विस्तार करने के लिए:

public static bool HasDefaultConstructor(this Type t) 
{ 
    return t.IsValueType || t.GetConstructor(Type.EmptyTypes) != null; 
} 

में सफलता के बाद से भी enum डिफ़ॉल्ट parameterless निर्माता है। प्रतिबिंब कॉल नहीं होने के बाद भी मूल्य प्रकारों के लिए थोड़ा सा गति।

1

मुझे केवल वैकल्पिक पैरामीटर के साथ कन्स्ट्रक्टरों की गिनती करने की आवश्यकता है जो वास्तविक पैरामीटर-कम कन्स्ट्रक्टर के समान हैं।ऐसा करने के लिए:

myClass.GetType().GetConstructors() 
    .All(c => c.GetParameters().Length == 0 || c.GetParameters().All(p => p.IsOptional)) 
संबंधित मुद्दे

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