7

式に、たとえばMemberExpressionでさらにラップされていないParameterExpressionが含まれているかどうかを確認する簡単な方法はありますか?

例:

x => x.Method() ? x : null<=1回のxの発生(それ以上の評価なし)

x => x.Method() ? x.Property : null<=0それ以上の評価なしのxの発生

簡単に言えば、私のユースケースは、メソッド(paramsなし)とプロパティ値を知っていて、ストアから「オブジェクト」全体をフェッチせずに式を評価するのにこれで十分かどうかを調べたいというものです。

編集:私の例はおそらく単純化することです。処理する必要のある式タイプは他にもあります(たとえば、UnaryExpression)。

x => ((Cast) x).Property<=0それ以上の評価なしのxの発生

私は次の質問に対する答えを探しています:

式が与えられた場合、入力パラメーターのすべてのメソッド戻り値とプロパティ値はわかっているが、パラメーター値自体はわかっていない場合、式を評価できますか?

4

1 に答える 1

1

.NET 4以降を使用している場合は、これを使用できますExpressionVisitor

「孤独なパラメーター」をどのように定義するかはよくわかりませんが、パラメーターに対する直接メソッド呼び出し、メンバーアクセス、インデクサーアクセスを除外する場合は、次のようなものを使用できます(テストされていません)。

次のように使用します。

new MyExpressionVisitor().GetNumLonelyParameterExpressions(myExpression.Body)

public class MyExpressionVisitor : ExpressionVisitor
{
    private int numLonelyParameterExpressions;

    public int GetNumLonelyParameterExpressions(Expression expression)
    {
        numLonelyParameterExpressions = 0;
        Visit(expression);
        return numLonelyParameterExpressions;
    }

    protected override Expression VisitParameter(ParameterExpression node)
    {
        // Every time we encounter a lonely parameter, increment.
        numLonelyParameterExpressions++;
        return base.VisitParameter(node);
    }

    protected override Expression VisitMethodCall(MethodCallExpression node)
    {
        // Don't visit parameters that have methods called on them.
         var expr = (node.Object is ParameterExpression)
            ? Expression.Default(node.Object.Type)
            : node.Object;

        // We need to make sure the arguments are visited though.
        return base.VisitMethodCall(node.Update(expr, node.Arguments));
    }


    protected override Expression VisitMember(MemberExpression node)
    {
          // Don't visit parameters with member accesses on them.
          if (node.Expression is ParameterExpression)
              return Expression.Default(node.Type);

          return base.VisitMember(node);
    }

    protected override Expression VisitIndex(IndexExpression node)
    {
         // Same idea here.
         var expr = (node.Object is ParameterExpression)
             ? Expression.Default(node.Object.Type)
             : node.Object;

         return base.VisitIndex(node.Update(expr, node.Arguments));
    }
}
于 2012-10-05T14:03:03.710 に答える