找出表达式是否包含"孤独"的ParameterExpression

lin*_*rik 7 c# expression

有没有一种简单的方法可以找出一个Expression是否包含一个没有进一步包含的ParameterExpression,例如一个MemberExpression.

例:

x => x.Method() ? x : null <= 1出现x而无需进一步评估

x => x.Method() ? x.Property : null <= 0出现x而没有任何进一步的评估

简单地说,我的用例是我知道Method(没有参数)和属性值,并想知道这是否足以评估表达式而不从存储中获取整个"对象".

编辑:我的例子可能是简化.需要处理更多表达式类型(例如,UnaryExpression).

x => ((Cast) x).Property <= 0出现x而没有任何进一步的评估

我正在寻找以下问题的答案:

给定一个表达式,如果我知道输入参数的所有方法返回值和属性值而不是参数值本身,我可以计算表达式吗?

Ani*_*Ani 1

如果您使用的是 .NET 4 或更高版本,则可以使用ExpressionVisitor此功能。

我不太确定你如何定义“孤独参数”,但如果你想排除参数上的直接方法调用、成员访问和索引器访问,你可以使用类似这样的东西(未经测试):

像这样使用它:

new MyExpressionVisitor().GetNumLonelyParameterExpressions(myExpression.Body)
Run Code Online (Sandbox Code Playgroud)
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));
    }
}
Run Code Online (Sandbox Code Playgroud)