Finding out if an expression contains a lone parameter expression

Is there an easy way to find out if an expression contains a ParameterExpression expression that is not completed, such as MemberExpression.

Example:

x => x.Method() ? x : null x => x.Method() ? x : null <= 1 occurrence x without additional evaluation

x => x.Method() ? x.Property : null x => x.Method() ? x.Property : null <= 0 occurrences of x without any further evaluation

Simply put, my use case is that I know the Method (no params) and Property parameters and want to know if this is enough to evaluate the expression without selecting the entire “object” from the repository.

Edit: My example may be simplified. There are more types of expressions that need to be processed (for example, UnaryExpression).

x => ((Cast) x).Property <= 0 occurrences of x without additional evaluation

I am looking for the answer to the following question:

for an expression, if I know all the return values ​​of the method and the property values ​​of the input parameter, but not the parameter value itself, can I evaluate the expression?

+7
source share
1 answer

If you are using .NET 4 or later, you can use ExpressionVisitor .

I'm not quite sure how you define a “lone parameter”, but if you want to exclude direct method calls, member calls and indexer calls to parameters, you can use something like this (untested):

Use it as follows:

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

All Articles