2

目的は、2 つの LambdaExpressions から MemberExpressions の配列を取得することです。1 つ目は、オブジェクトのインスタンスを返す MethodCallExpression に変換できます ( Expression<Func<T>>)。2 番目の Lambda 式は、コンパイルされた最初の式の結果を取得し、ネストされたメンバー ( Expression<Func<T,TMember>>) を返します。2 番目の Lambda 式は、ネストされたプロパティの呼び出しのみを行うと想定できますが、これらの呼び出しのいくつかを行う可能性があります。

したがって、作成しようとしているメソッドのシグネチャは次のとおりです。

MemberExpression[] GetMemberExpressionArray<T,TValue>(Expression<Func<T>> instanceExpression, Expression<Func<T,TValue>> nestedMemberExpression)

wherenestedMemberExpressionは次の形式の引数を取ると想定されます

parent => parent.ChildProperty.GrandChildProperty

parent結果の配列は、 toおよびtoChildPropertyの値からの MemberAccess を表します。 ChildPropertyGrandChildProperty

MemberExpression次の拡張メソッドを使用して、すでに最後のものを返しました。

public static MemberExpression GetMemberExpression<T, TValue>(Expression<Func<T, TValue>> expression)
{
    if (expression == null)
    {
        return null;
    }
    if (expression.Body is MemberExpression)
    {
        return (MemberExpression)expression.Body;
    }
    if (expression.Body is UnaryExpression)
    {
        var operand = ((UnaryExpression)expression.Body).Operand;
        if (operand is MemberExpression)
        {
            return (MemberExpression)operand;
        }
        if (operand is MethodCallExpression)
        {
            return ((MethodCallExpression)operand).Object as MemberExpression;
        }
    }
    return null;
} 

さて、これを達成するにはいくつかの方法があることを私は知っています。私にとって最も直感的な方法は、.Expressionプロパティをループして最初の式を取得し、途中で各 MemberExpression への参照をキャプチャすることです。これが最善の方法かもしれませんが、そうではないかもしれません。このような式を使用することで得られるパフォーマンス コストについて、私はあまりよく知りません。MemberExpression には MemberInfo があり、リフレクションがパフォーマンスを低下させるはずであることを知っています。

式に関する情報を検索しようとしましたが、見つけたリソースは非常に限られています。

最適なパフォーマンスと信頼性でこのタスク (およびこのタイプのタスク全般) を達成する方法についてアドバイスをいただければ幸いです。

4

1 に答える 1

1

これがperformanceとタグ付けされた理由はわかりませんが、ツリーからメンバー式を抽出する最も簡単なExpressionVisitor方法は、サブクラス化することです。これは、さまざまなタイプの式を「展開」してツリーをたどるロジックを手動で記述するよりもはるかに簡単です。

VisitMemberおそらく、次のようにメソッドをオーバーライドする必要があります。

  1. 各メンバー式がキャプチャされます。
  2. その子供たちが訪問されます。

それは次のようになると思います:

protected override Expression VisitMember(MemberExpression node)
{
    _myListOfMemberExpressions.Add(node);
    return base.VisitMember(node);
}

あなたの仕事の残りの部分については、少しよくわかりません。パラメータ式を書き換えたいようです。その場合は、Marc Gravell からのこの回答を参照してください。

于 2011-02-10T17:32:22.900 に答える