Combine 2 expressions using Expression API

  • Thread starter Thread starter _gh_manvel_
  • Start date Start date
G

_gh_manvel_

Guest
I'm trying to combine map & filter expressions into one

public static Expression<Func<T, bool>> Combine<T, U>(this Expression<Func<T, U>> map,
Expression<Func<U, bool>> filter)


If I would have the same with Func's I would have

public static Func<T, bool> Combine<T, U>(this Func<T, U> map,
Func<U, bool> filter) => input => filter(map(input));


I'm trying to construct the same via C# expressions API, but can't make it work. Here's how far I got

public static Expression<Func<T, bool>> Combine<T, U>(this Expression<Func<T, U>> map,
Expression<Func<U, bool>> filter)
{
ParameterExpression tVariableExpression = Expression.Variable(typeof(U), "u");
Expression converter = Expression.Assign(tVariableExpression, map.Body);

ParameterExpression resultExpression = Expression.Variable(typeof(bool), "result");
Expression predicate = Expression.Assign(resultExpression, filter.Body);

var block = Expression.Block(
new[] { tVariableExpression, resultExpression },
converter, predicate);

return Expression.Lambda<Func<T, bool>>(block, map.Parameters);
}


And here's the usage

Expression<Func<string, int>> stringToInt = text => text.Length;
Expression<Func<int, bool>> lengthToBool = length => length % 2 == 0;

var combined = stringToInt.Combine(lengthToBool);

var compiledCombined = combined.Compile();

var odd = compiledCombined.Invoke("Foo");


If I run this, I get the following error when compiling lambda.

System.InvalidOperationException: 'variable 'length' of type 'System.Int32' referenced from scope '', but it is not defined'


What am I'm doing wrong here ? How can I make this work ?

Continue reading...
 
Back
Top