web-dev-qa-db-ja.com

MemberInfoの値を取得するにはどうすればよいですか?

MemberInfoオブジェクトの値を取得するにはどうすればよいですか? .Nameは変数の名前を返しますが、値が必要です。

FieldInfoでこれができると思いますが、私はスニペットを持っていません。これを行う方法を知っている場合は、スニペットを提供できますか?

ありがとう!

31

FieldInfo.GetValue を使用したフィールドの例を次に示します。

using System;
using System.Reflection;

public class Test
{
    // public just for the sake of a short example.
    public int x;

    static void Main()
    {
        FieldInfo field = typeof(Test).GetField("x");
        Test t = new Test();
        t.x = 10;

        Console.WriteLine(field.GetValue(t));
    }
}

同様のコードは PropertyInfo.GetValue() を使用してプロパティに対して機能します。ただし、パラメーターの値をプロパティに渡す必要もあります。 (「通常の」C#プロパティには何もありませんが、フレームワークに関する限り、C#インデクサーはプロパティとしてカウントされます。)メソッドの場合、必要に応じて Invoke を呼び出す必要があります。メソッドを呼び出して戻り値を使用します。

32
Jon Skeet

マークを反省しないという点には概ね同意しますが、必要な場合もあります。メンバーを反映​​する必要があり、それがフィールドであるかプロパティであるかを気にしない場合は、この拡張メソッドを使用して値を取得できます(値ではなくタイプが必要な場合は、nawfulの回答を参照してください この質問 ):

    public static object GetValue(this MemberInfo memberInfo, object forObject)
    {
        switch (memberInfo.MemberType)
        {
            case MemberTypes.Field:
                return ((FieldInfo)memberInfo).GetValue(forObject);
            case MemberTypes.Property:
                return ((PropertyInfo)memberInfo).GetValue(forObject);
            default:
                throw new NotImplementedException();
        }
    } 
22
Eric Hewitt

ジョンの答えは理想的です-ただ一つの観察:一般的なデザインの一部として、私は:

  1. 一般に非公開メンバーに対して反射を避ける
  2. パブリックフィールドを避ける(ほとんどの場合)

これら2つの効果の概要は、一般にパブリックプロパティに対してリフレクションする必要があるだけです(それらが何をしているかを知らない限り、メソッドを呼び出すべきではありません。プロパティゲッターは期待されるべき等である[遅延ロードは別として])。したがって、PropertyInfoの場合、これはprop.GetValue(obj, null);です。

実際、私はSystem.ComponentModelの大ファンなので、次のように使いたくなります。

    foreach(PropertyDescriptor prop in TypeDescriptor.GetProperties(obj))
    {
        Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(obj));
    }

または特定のプロパティ:

    PropertyDescriptor prop = TypeDescriptor.GetProperties(obj)["SomeProperty"];
    Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(obj));

System.ComponentModelの1つの利点は、DataViewが列を仮想プロパティとして公開する方法など、抽象化されたデータモデルで機能することです。他にもトリックがあります( パフォーマンストリック など)。

11
Marc Gravell