2010-09-14 11 views
5

सी # में मैं default(T) का उपयोग किसी प्रकार का डिफ़ॉल्ट मान प्राप्त करने के लिए कर सकता हूं। मुझे System.Type से रन टाइम पर डिफ़ॉल्ट प्रकार प्राप्त करने की आवश्यकता है। मैं यह कैसे कर सकता हूँ?मैं एक प्रकार के साथ डिफ़ॉल्ट (टी) कैसे कॉल कर सकता हूं?

उदा। इस की तर्ज पर कुछ (जो काम नहीं करता है)

var type = typeof(int); 
var defaultValue = default(type); 

उत्तर

9

एक संदर्भ प्रकार के लिए null, एक मान प्रकार के लिए, आप Activator.CreateInstance का उपयोग करके या प्रकार के डिफ़ॉल्ट निर्माता को कॉल करने का प्रयास कर सकते हैं।

public static object Default(Type type) 
{ 
    if(type.IsValueType) 
    { 
     return Activator.CreateInstance(type); 
    } 

    return null; 
} 
+1

मेरे प्रश्न लिखने के कुछ ही समय बाद मैं 'रिटर्न एक्सप्रेशन' के साथ आया। Lambda > (अभिव्यक्ति। कनवर्ट करें (अभिव्यक्ति.डिफॉल्ट (प्रकार), टाइपऑफ (ऑब्जेक्ट)))। संकलित()(); ', लेकिन आपका बहुत अच्छा है। – GiddyUpHorsey

+0

@Giddy: यह करने का एक बहुत ही महंगा तरीका होगा, क्योंकि आप अभिव्यक्ति के पेड़ को आईएल में संकलित कर रहे हैं (और उसके बाद जेआईटी को इसे मूल रूप से संकलित करना होगा) प्रत्येक आमंत्रण पर। –

+0

हां, मैं सहमत हूं। यही कारण है कि मैं इसका उपयोग नहीं कर रहा हूं, और इसके बजाय मैडोगोम के समाधान का उपयोग कर रहा हूं। हालांकि, यह छोटा और अधिक पठनीय कोड था, प्रदर्शन नहीं, जिसने मुझे उसका उपयोग करने के लिए प्रेरित किया।प्रदर्शन मेरे परिदृश्य के लिए एक सौदा का बड़ा नहीं है। – GiddyUpHorsey

6

आप एक अभिव्यक्ति पेड़ बनाने की कोशिश कर रहे हैं, का उपयोग Expression.Default:

Expression expression = Expression.Default(type); 

का एक दूसरा तरीका आप कर सकता है यह काफी आसानी से होगा:

object defaultValue = Array.CreateInstance(type, 1).GetValue(0); 

बदसूरत, लेकिन यह, :) ध्यान दें कि किसी नल प्रकार का डिफ़ॉल्ट मान प्राप्त करने के लिए मुश्किल है काम करेंगे के रूप में यह होगा एक lways एक शून्य संदर्भ के लिए बॉक्स किया जाना चाहिए।

के रूप में टिप्पणी में बताया गया है, कुछ अस्पष्ट परिदृश्यों (void और सूचक प्रकार) जहां इन बराबर नहीं कर रहे हैं, लेकिन वे कोने मामलों :)

+1

मैं Mindscape Lightspeed साथ प्रयोग के लिए अभिव्यक्ति के पेड़ पैदा कर रहा हूँ, लेकिन उनके क्वेरी प्रदाता का समर्थन नहीं करता 'DefaultExpression', तो मैं वास्तविक मूल्य की जरूरत है एक 'ConstantExpression' अंदर डाल करने के लिए। – GiddyUpHorsey

+0

मामूली नाइटपिकिंग का सबसे हल्का, व्यवहार सूचक प्रकार के लिए अलग है। 'डिफॉल्ट (int *) 'रिटर्न' IntPtr.Zero', जबकि 'डिफ़ॉल्ट (टाइपऑफ (int *))' फेंकता है। मैंने पाया है कि एक और अस्पष्ट क्षेत्र 'System.Void' के लिए है, आप' डिफ़ॉल्ट (शून्य) 'नहीं कर सकते हैं जबकि' डिफ़ॉल्ट (टाइपऑफ (शून्य)) 'रिटर्न शून्य। कोई बड़ी बात नहीं, बस अगर कोई ख्याल रखना चाहता है .. – nawfal

+0

@nawfal: उस प्रभाव को धन्यवाद, धन्यवाद। –

3

कि बहुत आसान है, तो आप सिर्फ 2 मामलों पर विचार करने के लिए है रहे हैं :

  • संदर्भ प्रकार: डिफ़ॉल्ट मान हमेशा अशक्त
  • मूल्य प्रकार है: आप आसानी से एक उदाहरण Activator.CreateInstance

    का उपयोग कर बना सकते हैं

आप Activator.CreateInstance के बजाय FormatterServices.GetUninitializedObject का उपयोग करने पर भी विचार कर सकते हैं, यह शायद तेज़ है।

+0

क्या आपने अपना कोड चलाने का प्रयास किया है? यह काम नहीं करेगा, और कारण यह है कि मूल्य प्रकार (सामान्यतः) में एक डिफ़ॉल्ट कन्स्ट्रक्टर नहीं होता है। वे सी # में करते हैं, लेकिन यह एक कथा है; सीएलआर स्तर पर कोई नहीं है, और आईएल में 'initobj' का उपयोग किया जाता है। –

+0

@ पावेल, आप सही हैं, मुझे कभी एहसास नहीं हुआ कि वास्तविक डिफॉल्ट कन्स्ट्रक्टर नहीं था ... मैंने इसे एक्टिवेटर में बदल दिया। क्रिएट इंस्टेंस, और यह ठीक काम करता है –

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

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