web-dev-qa-db-ja.com

リフレクションを使用してプロパティの文字列名を取得

次のいずれかを取得できるリフレクションの例が豊富にあります。

    1.クラス内のすべてのプロパティ

    2.文字列名を知っている場合、単一のプロパティ

クラスとプロパティのインスタンスさえあれば、実行時にクラスのプロパティの文字列名を取得する方法(リフレクション、TypeDescriptorなどを使用)はありますか?

[〜#〜] edit [〜#〜]リフレクションを使用してクラス内のすべてのプロパティを簡単に取得し、各プロパティの名前を取得できることを知っています。私が求めているのは、プロパティのインスタンスを渡すことを条件に、プロパティの名前を与える関数です。つまり、class.GetType()。GetProperty(myProperty)から返されたPropertyInfo []配列から必要なプロパティを見つけて、そこからPropertyInfo.Nameを取得できるようにするにはどうすればよいですか?

45
Joel B

既にPropertyInfoを持っている場合、@ dtbの答​​えは正しいものです。ただし、現在のプロパティのコードを見つけたい場合は、現在の呼び出しスタックを走査して、現在実行しているメソッドを見つけ、そこからプロパティ名を導出する必要があります。

var stackTrace = new StackTrace();
var frames = stackTrace.GetFrames();
var thisFrame = frames[0];
var method = thisFrame.GetMethod();
var methodName = method.Name; // Should be get_* or set_*
var propertyName = method.Name.Substring(4);

編集:

あなたの説明の後、私はあなたが何をしたいのかは、プロパティからプロパティの名前を取得するのだろうかと思っていますexpression。もしそうなら、次のようなメソッドを書きたいかもしれません:

public static string GetPropertyName<T>(Expression<Func<T>> propertyExpression)
{
    return (propertyExpression.Body as MemberExpression).Member.Name;
}

これを使用するには、次のように記述します。

var propertyName = GetPropertyName(
    () => myObject.AProperty); // returns "AProperty"
89
Jacob

C#6.0(Visual Studio 2015)では、次のようにnameof演算子を使用できるようになりました。

var obj = new MyObject();
string propertyName = nameof(obj.Property);
string methodName = nameof(obj.Method);
string directPropertyName = nameof(MyObject.Property);
string directMethodName = nameof(MyObject.Method);
47
saluce
13
dtb

誰かがそれを必要とする場合...ここにVB .NETバージョンの答え:

Public Shared Function GetPropertyName(Of t)(ByVal PropertyExp As Expression(Of Func(Of t))) As String
   Return TryCast(PropertyExp.Body, MemberExpression).Member.Name
End Function

使用法:

Dim name As String = GetPropertyName(Function() (New myObject).AProperty)
5
TKTS

正確にはTKTSによって書かれた正しい答えであり、ここでは彼の構文をC#に変換したいだけです

public static string GetPropertyName<t>(Expression<Func<t>> PropertyExp)
{
return (PropertyExp.Body as MemberExpression).Member.Name;
}

このコードの使用法は、次の例のようになります。

string name = GetPropertyName(() => (new Tasks()).Title);

さらに、例外が発生する可能性があります。すべてのプロパティにnull値があるため、コードを実装するときに誰もが集中する必要があります

ありがとうTKTS ..

3
Ahmad Hindash

myClassInstance.GetType().GetProperties()は、PropertyInfo型のすべてのパブリックプロパティのmyClassInstanceインスタンスを提供します。 (ドキュメントおよびその他のオーバーロードについては [〜#〜] msdn [〜#〜] を参照してください。) 'PropertyInfo.Name'はプロパティの実際の名前です。プロパティの名前がす​​でにわかっている場合は、GetProperty(name)を使用してPropertyInfoオブジェクトを取得します( [〜#〜] msdn [〜#〜] を再度参照) 。

0
Ondrej Tucny

Jacobが提供するバージョンを使用しましたが、例外が発生する場合がありました。キャストが無効だったためです。このバージョンは問題を解決しました:

    public static string GetPropertyName<T>(this Expression<Func<T>> propertyExpression)
    {
        ConstantExpression cExpr = propertyExpression.Body as ConstantExpression;
        MemberExpression mExpr = propertyExpression.Body as MemberExpression;

        if (cExpr != null)
            return cExpr.Value.ToString();
        else if (mExpr != null)
            return mExpr.Member.Name;

        else return null;
    }
0
Michael Bahig