2012-12-23 16 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; 
     } 
    } 

それはオプションのパラメータのデフォルト値を取得するためにリフレクションを使用して可能ですか? ParameterInfoクラスの

答えて

6

は、基本的なプログラムを取ることができます。 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 

.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コールの一部としてハードコードしていることに注意してください、とのFooインチ呼び出しメソッドは実際にはオプションの値をハードコーディングしています!値は、呼び出しサイトと呼び出し先サイトの両方にあります。

あなたはフォームを使用して、オプションの値で取得することができます:(他の回答で述べた)のDefaultValueためのMSDNで

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

このプロパティがあります実行コンテキストでのみ使用されます。反射のみのコンテキストでは、代わりにRawDefaultValueプロパティを使用します。

そして最後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 - コンストラクタのtypoを修正しました。 dはSOで使用; O – BlueChippy

+0

これは違いがあります。その場合、GetMethod()の代わりに[type] .GetConstructor()を使用します。 –

+0

答えは、相違点を説明するために更新されました。 1から2を変更して3番目のオプション値を取得することができます。私はこれをテストし、それは私のマシン上で動作し、[RawDefaultValueの代わりに] DefaultValue [リフレクションのコンテキストに応じて動作する必要があります。 –

1

DefaultValueは、あなたが探しているものです。

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

そして、いくつかのILコードを見て:

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

オブジェクト参照がオブジェクトのインスタンスに設定されていません。 – BlueChippy

+0

実際にあなたの最初の投稿では、いくつかのAbstractClassToTestSomeClassメソッドを参照していましたが、編集されたバージョンでは、オプションのパラメータを持つコンストラクタが上記の編集をチェックします –

関連する問題