2012-12-23 44 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

讓我們的基本程序:

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

,看看哪些IL代碼。

對於富:

.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硬編碼爲呼叫的一部分,並且在富。調用方法實際上是對可選的值進行硬編碼!該值位於呼叫站點和被呼叫者站點。

您可以通過使用形式的可選值來獲得:

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

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

lol - 修復構造函數中的錯字...從另一個例子複製我' d用於SO; O – BlueChippy

+0

這將有所作爲。在這種情況下,您將需要使用[type] .GetConstructor()而不是GetMethod()。 –

+0

答覆已更新,以解決差異。您可以將1更改爲2以獲取第三個可選值。我測試了它,它在我的機器上工作,並且DefaultValue [而不是RawDefaultValue]也應該取決於反射的上下文。 –

1

ParameterInfoDefaultValue是你在找什麼:

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

對象引用不設置爲一個對象的一個​​實例。 – BlueChippy

+0

實際上,在你的第一篇文章中,你引用了一些AbstractClassToTestSomeClass方法,而在編輯版本中它的構造函數帶有可選參數,請檢查上面的編輯 –

相關問題