2012-12-23 18 views
5

böyle bir sınıf Verilen:Yansımayı kullanarak bir yapıcıdan isteğe bağlı parametre değerlerini almak mümkün mü?

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; 
     } 
    } 

bu isteğe parametrenin varsayılan değerlerini almak için yansıma kullanmak mümkün olabilir mi? ParameterInfo sınıfın

cevap

6

temel programı çekmenize imkan verir. Foo için

: Main İçin

.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 

ana 5 çağrısının bir parçası olarak önceden kodlanmıştır ettiğini Bildirim ve Foo içinde. Çağrı yöntemi aslında isteğe bağlı olan değeri kodlamaktır! Değer, hem arama sitesi hem de aranan site.

Sen formu kullanarak opsiyonel değerde olsun mümkün olacaktır:

defaultValue için MSDN (diğer cevapta belirtildiği) Açık

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

:

Bu özelliktir sadece yürütme bağlamında kullanılır. Yalnızca yansıtma bağlamında, RawDefaultValue özelliğini kullanın.

Ve nihayet bir POC MSDN:

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 üzerindeki düzenlemeyi gözden geçirin - yazım hatalarını düzelticiye sabitlediniz ... SO üzerinde kullanılır; O – BlueChippy

+0

Bu bir fark yaratacaktır. Bu durumda, GetMethod() yerine [type] .GetConstructor() kullanmak isteyeceksiniz. –

+0

Farkı dikkate almak için yanıt güncellendi. Üçüncü isteğe bağlı değeri almak için 1 ila 2 arasında değişiklik yapabilirsiniz. Bunu test ettim ve makinem üzerinde çalışıyor ve DefaultValue [RawDefaultValue] yerine yansımanın içeriğine bağlı olarak da çalışmalıdır. –

1

DefaultValue Aradığınız şudur:

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

Ve bazı IL Kodu bakmak:

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

nesne başvurusu bir nesnenin örneğine ayarlanmadı. – BlueChippy

+0

Aslında ilk yazınızda, bazı AbstractClassToTestSomeClass yöntemine başvuruda bulunmuştunuz, düzenlenmiş sürümde ise isteğe bağlı parametreli yapıcı, –

İlgili konular