2012-10-05 40 views
7

有没有一种简单的方法来确定一个表达式是否包含一个不包含在例如MemberExpression中的ParameterExpression。查找表达式是否包含“孤独”参数表达式

实施例:

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

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

简而言之我的使用情况是,我知道方法(没有参数)和属性值,并且想知道这是否足以评估表达式而不从存储中获取整个“对象”。

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

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

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

给出的表达式,如果我知道的所有方法的返回值和属性值输入参数但不是参数值本身,我可以评估表达式吗?

+0

什么版本的.NET您使用的是? –

+0

它的.net 3.5(但我也有一个.net 4版本,我可以使用这个) – lindstromhenrik

回答

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)); 
    } 
} 
+0

这是我目前的做法(我有我自己的ExpressionVisitor 3.5)。然而,还有更多的表达式需要计数,我担心我会错过一些表达式。例如UnaryExpression:x =>((Cast)x).Property。 – lindstromhenrik

+0

@lindstromhenrik:我想你将不得不很好地定义'寂寞',就好像你包含那样,它非常含糊。 – Ani

+0

我试图给出一个更好的解释,但我仍然不知道该怎么称呼这个问题;-) – lindstromhenrik

相关问题