2012-12-23 9 views
5

इस तरह एक वर्ग को देखते हुए:क्या प्रतिबिंब का उपयोग कर एक निर्माता से वैकल्पिक पैरामीटर मान प्राप्त करना संभव है?

public abstract class SomeClass 
    { 
     private string _name; 
     private int _someInt; 
     private int _anotherInt; 

     public SomeClass(string name, int someInt = 10, int anotherInt = 20) 
     { 
      _name = name; 
      _someInt = someInt; 
      _anotherInt = anotherInt; 
     } 
    } 

यह प्रतिबिंब का उपयोग वैकल्पिक पैरामीटर के डिफ़ॉल्ट मान प्राप्त करना संभव है?

उत्तर

6

एक बुनियादी कार्यक्रम लेते हैं।

फू के लिए:

.method public hidebysig static void Foo([opt] int32 i) cil managed 
{ 
    .param [1] = int32(0x00000005) 
    // Code size  24 (0x18) 
    .maxstack 8 
    IL_0000: nop 
    IL_0001: ldstr  "hi" 
    IL_0006: ldarg.0 
    IL_0007: box  [mscorlib]System.Int32 
    IL_000c: call  string [mscorlib]System.String::Concat(object, 
                   object) 
    IL_0011: call  void [mscorlib]System.Console::WriteLine(string) 
    IL_0016: nop 
    IL_0017: ret 
} // end of method Program::Foo 

मुख्य लिए:

.method private hidebysig static void Main(string[] args) cil managed 
{ 
    .entrypoint 
    // Code size  9 (0x9) 
    .maxstack 8 
    IL_0000: nop 
    IL_0001: ldc.i4.5 
    IL_0002: call  void ConsoleApplication3.Program::Foo(int32) 
    IL_0007: nop 
    IL_0008: ret 
} // end of method Program::Main 

सूचना है कि मुख्य 5 कॉल के हिस्से के रूप hardcoded गया है, और फू में। कॉलिंग विधि वास्तव में उस मान को हार्डकोड कर रही है जो वैकल्पिक है! मूल्य कॉल-साइट और कैली साइट दोनों पर है।

आप फ़ॉर्म का उपयोग करके वैकल्पिक मूल्य पर प्राप्त करने में सक्षम हो जाएगा:

typeof(SomeClass).GetConstructor(new []{typeof(string),typeof(int),typeof(int)}) .GetParameters()[1].RawDefaultValue

DefaultValue के लिए MSDN (अन्य जवाब में बताया गया) पर:

यह गुण है केवल निष्पादन संदर्भ में प्रयोग किया जाता है। प्रतिबिंब-केवल संदर्भ में, इसके बजाय RawDefaultValue प्रॉपर्टी का उपयोग करें। MSDN

और अंत में एक POC:

static void Main(string[] args) 
{ 
    var optionalParameterInformation = typeof(SomeClass).GetConstructor(new[] { typeof(string), typeof(int), typeof(int) }) 
    .GetParameters().Select(p => new {p.Name, OptionalValue = p.RawDefaultValue}); 

    foreach (var p in optionalParameterInformation) 
     Console.WriteLine(p.Name+":"+p.OptionalValue); 

    Console.ReadKey(); 
} 

http://bartdesmet.net/blogs/bart/archive/2008/10/31/c-4-0-feature-focus-part-1-optional-parameters.aspx

+0

लॉल से ऊपर संपादित करें देखें - कन्स्ट्रक्टर में टाइपो को ठीक किया गया है ... मैं एक और उदाहरण से कॉपी कर रहा था। डी एसओ पर प्रयोग किया जाता है; ओ – BlueChippy

+0

इससे कोई फर्क पड़ता है। उस स्थिति में आप GetMethod() के बजाय [type] .GetConstructor() का उपयोग करना चाहेंगे। –

+0

उत्तर के लिए खाते में अपडेट किया गया उत्तर। तीसरा वैकल्पिक मान प्राप्त करने के लिए आप 1 से 2 बदल सकते हैं। मैंने इसका परीक्षण किया और यह मेरी मशीन पर काम करता है, और DefaultValue [RawDefaultValue के बजाय] प्रतिबिंब के संदर्भ के आधार पर भी काम करना चाहिए। –

1

ParameterInfo वर्ग के DefaultValue आप के लिए क्या देख रहे है:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Foo(); 
    } 
    public static void Foo(int i = 5) 
    { 
     Console.WriteLine("hi" +i); 
    } 
} 

और कुछ आईएल कोड को देखो:

var defaultValues = typeof(SomeClass).GetConstructors()[0].GetParameters().Select(t => t.DefaultValue).ToList(); 
+1

वस्तु संदर्भ एक वस्तु का एक उदाहरण के लिए सेट नहीं। – BlueChippy

+0

वास्तव में आपकी पहली पोस्ट में, आपने कुछ सार क्लासटॉस्टस्टोम क्लास विधि का संदर्भ दिया है, जबकि संपादित संस्करण में इसके वैकल्पिक पैरामीटर के साथ कन्स्ट्रक्टर, –

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