2

私は次の拡張メソッドを持っています:

public static string ToPropertyName<T,E>(this Expression<Func<E, T>> propertyExpression)
{
    if (propertyExpression == null)
        return null;

    string propName;
    MemberExpression propRef = (propertyExpression.Body as MemberExpression);
    UnaryExpression propVal = null;

    // -- handle ref types
    if (propRef != null)
        propName = propRef.Member.Name;
    else
    {
        // -- handle value types
        propVal = propertyExpression.Body as UnaryExpression;
        if (propVal == null)
            throw new ArgumentException("The property parameter does not point to a property", "property");
        propName = ((MemberExpression)propVal.Operand).Member.Name;
    }

    return propName;
}

文字列の代わりにプロパティ名を渡すときにlinq式を使用して強い型付けを提供し、この関数を使用してプロパティの名前を文字列として取得します。この方法は反射を使用しますか?

私が尋ねる理由は、このメソッドがコードで非常に頻繁に使用されており、十分に高速であることを望んでいるためです。

4

2 に答える 2

2

私の知る限り、反射は、ある種の動的なタイプのイントロスペクションが舞台裏で行われるという意味では関与していません。ただし、またはSystem.Reflectionなどの型は、名前空間の型と一緒に使用されます。これらは、メソッドに渡されたものを抽象構文木(AST)として記述するためにのみコンパイラーによって使用されます。aから式ツリーへのこの変換は、実行時ではなくコンパイラによって行われるため、ラムダの静的な側面のみが説明されています。TypePropertyInfoSystem.Linq.ExpressionsFunc<T,E>Func<T,E>

ただし、実行時にラムダからこの式ツリー(複雑なオブジェクトグラフ)を構築するには、インスタンス化する必要のあるオブジェクトを増やす必要があるため、プロパティ名の文字列(単一のオブジェクト)を渡すよりも多少時間がかかる場合があります(数は複雑さによって異なります)。メソッドに渡されたラムダの)が、繰り返しになりますが、動的型検査someObject.GetType()は含まれていません。

例:

このMSDNの記事は、次のラムダ式を示しています。

Expression<Func<int, bool>> lambda1 = num => num < 5;

コンパイラによって次のようなものに変換されます。

ParameterExpression numParam = Expression.Parameter(typeof(int), "num");
ConstantExpression five = Expression.Constant(5, typeof(int));
BinaryExpression numLessThanFive = Expression.LessThan(numParam, five);
Expression<Func<int, bool>> lambda1 =
    Expression.Lambda<Func<int, bool>>(
        numLessThanFive,
        new ParameterExpression[] { numParam });

これを超えると、他に何も起こりません。したがって、これは、メソッドに渡される可能性のあるオブジェクトグラフです。

于 2012-07-06T08:50:48.107 に答える
0

メソッドの命名はですのでToPropertyName、クラスの特定のプロパティの型付き名を取得しようとしていると思います。Expression<Func<E, T>>アプローチのベンチマークを行いましたか?式を作成するコストは非常に高く、メソッドは静的であるため、メンバー式もキャッシュしていないようです。言い換えれば、表現アプローチがリフレクションを使用しない場合でも、コストが高くなる可能性があります。この質問を参照してください:リフレクション付きの文字列としてC#プロパティ名を取得するにはどうすればよいですか?別のアプローチがある場合:

public static string GetName<T>(this T item) where T : class
{
    if (item == null)
        return string.Empty;

    return typeof(T).GetProperties()[0].Name;
}

これを使用して、次のようにプロパティまたは変数の名前を取得できます。

new { property }.GetName();

さらにスピードアップするには、メンバー情報をキャッシュする必要があります。あなたが持っているものが絶対Func<E, T>にあるなら、あなたのアプローチは適しています。こちらもご覧ください:ラムダ式ベースのリフレクションと通常のリフレクション

関連する質問:すべてのプロパティ名と対応する値を辞書に入れる

于 2013-04-17T10:32:53.733 に答える