2012-12-23 3 views

Antwort

6

Lässt ein Basisprogramm nehmen:

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

Und Blick auf einige IL-Code.

für Foo:

.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 

Für Main:

.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 

Beachten Sie, dass Haupt-5 als Teil des Aufrufs fest einprogrammiert hat, und in Foo. Die Aufrufmethode schreibt tatsächlich den Wert, der optional ist, fest! Der Wert ist sowohl auf der Call-Site als auch auf der Callee-Site.

können Sie auf dem optionalen Wert erhalten, indem das Formular:

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

auf MSDN für Default (in der anderen Antwort erwähnt):

Diese Eigenschaft ist wird nur im Ausführungskontext verwendet. Verwenden Sie stattdessen im reflection-only-Kontext die RawDefaultValue-Eigenschaft. MSDN

Und schließlich ein 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

lol - korrigiert den Tippfehler im Konstruktor ... Kopieren von einem anderen Beispiel I ' d verwendet auf SO; O – BlueChippy

+0

Das wird einen Unterschied machen. In diesem Fall sollten Sie [type] .GetConstructor() anstelle von GetMethod() verwenden. –

+0

Antwort aktualisiert, um den Unterschied zu berücksichtigen. Sie können 1 bis 2 ändern, um den dritten optionalen Wert zu erhalten. Ich habe das getestet und es funktioniert auf meinem Rechner, und DefaultValue [anstelle von RawDefaultValue] sollte auch abhängig vom Kontext der Reflektion funktionieren. –

1

DefaultValue der ParameterInfo Klasse ist, was Sie suchen:

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

Objektverweis auf eine Instanz eines Objekts eingestellt. – BlueChippy

+0

Eigentlich in Ihrem ersten Post, Sie verwiesen auf einige AbstractClassToTestSomeClass-Methode, während in der bearbeiteten Version ist der Konstruktor mit optionalen Parameter, überprüfen Sie die Bearbeitung über –

Verwandte Themen