7

是否有一种简单的方法可以确定表达式是否包含未进一步包装的 ParameterExpression,例如 MemberExpression。

例子:

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

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

简单地说,我的用例是我知道方法(无参数)和属性值,并想知道这是否足以评估表达式而无需从存储中获取整个“对象”。

编辑:我的例子可能是为了简化。还有更多的表达式类型需要处理(例如 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 回答