Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing an expression tree as a parameter to another expression tree

I have two expression trees defined like this:

private Expression<Func<TEntity, TPropertyResult>> PropertyAccessor { get; set; }

and

private Expression<Func<TPropertyResult, bool>> TestExpression { get; set; }

I need to create a new expression tree that will result in the equivalent of:

var expression = p => this.TestExpression(this.PropertyAccessor(p));

When using Expression.Invoke(this.TestExpression, this.PropertyAccessor), I get the following error

{"Expression of type 'System.Func`2[MyEntity,System.String]' cannot be used for parameter of type 'System.String'"}

TPropertyResult is a string during my test.

I tried using Expression.Call or Expression.Invoke. No luck. What should I use?

like image 931
Pierre-Alain Vigeant Avatar asked Aug 19 '10 01:08

Pierre-Alain Vigeant


People also ask

What are expression trees represent the following expression using a tree?

Expression trees represent code in a tree-like data structure, where each node is an expression, for example, a method call or a binary operation such as x < y . You can compile and run code represented by expression trees.

How do you use expression trees?

When you want to have a richer interaction, you need to use Expression Trees. Expression Trees represent code as a structure that you can examine, modify, or execute. These tools give you the power to manipulate code during run time. You can write code that examines running algorithms, or injects new capabilities.

What is expression trees and how they used in LINQ?

Expression Trees was first introduced in C# 3.0 (Visual Studio 2008), where they were mainly used by LINQ providers. Expression trees represent code in a tree-like format, where each node is an expression (for example, a method call or a binary operation such as x < y).

What is an expression tree give an example in data structure?

The expression tree is a tree used to represent the various expressions. The tree data structure is used to represent the expressional statements. In this tree, the internal node always denotes the operators. The leaf nodes always denote the operands.


1 Answers

I think this does what you are asking for:

Expression<Func<TEntity, bool>> Combined
{
    get
    {
        var entity = Expression.Parameter(typeof(TEntity));
        var pa = Expression.Invoke(PropertyAccessor, entity);
        var te = Expression.Invoke(TestExpression, pa);
        return (Expression<Func<TEntity, bool>>) Expression.Lambda(te, entity);
    }
}

I tested this and it works as I would expect.

However, re-reading your original question (before my edits), I am beginning to get the impression that you asked the wrong question and that you probably don’t need expression trees. If all you need is functions, then you can use them without Expression:

private Func<TEntity, TPropertyResult> PropertyAccessor { get; set; }
private Func<TPropertyResult, bool> TestExpression { get; set; }
private Func<TEntity, bool> Combined
{
    get
    {
        return entity => TestExpression(PropertyAccessor(entity));
    }
}

Example of use:

// Set up the original functions
PropertyAccessor = entity => GenerateResult(entity);
TestExpression = result => result.IsCool();

// This stores a reference to the combined function
var fn = Combined;

// This actually evaluates the function
bool isCool = fn(myEntity);

// Alternatively, you could evaluate the function directly, without the variable
bool isCool = Combined(myEntity);
like image 84
Timwi Avatar answered Oct 18 '22 21:10

Timwi