Crear Func de MemberExpression y constante

.net c# expression expression-trees lambda

Pregunta

No hago el trabajo del árbol de expresiones lo suficiente para que esto funcione ...

Esencialmente, lo que quiero crear es m.MyProperty == 1 , para usar en un método que toma Func<T, bool> .

Ya tengo una MemberExpression . He intentado varias cosas, pero sigo teniendo errores diferentes.

Actualmente tengo algo como esto (que no funciona):

object const = 1;
var equalExpression = Expression.Equal( memberExpression, Expression.Constant( const ) );
var compiled = Expression.Lambda<Func<T, bool>>( equalExpression, Expression.Parameter( typeof( T ) ).Compile();

Esto me da una excepción:

System.InvalidOperationException: variable 'm' de tipo 'MyType' referenciada desde el alcance '', pero no está definida

He intentado volver a trabajar varias partes diferentes de esto, pero no he encontrado nada que funcione.

La const es un objeto que puede ser de cualquier tipo, pero debe coincidir con el tipo de MemberExpression .

Solución:

object c = 1;
var parameterExpression = (ParameterExpression)memberExpression.Expression;
var equalExpression = Expression.Equal(memberExpression, Expression.Constant(c));
var compiled = Expression.Lambda<Func<T, bool>>(equalExpression, parameterExpression).Compile();

Respuesta aceptada

La razón por la que esto no funciona es que está utilizando una expresión de parámetro "independiente" al compilar su lambda. Debería crear Expression.Parameter( typeof( T )) antes de hacer su memberExpression , y usar la misma instancia de ParameterExpression tanto cuando haga una expresión miembro como cuando compile el lambda:

var pe = Expression.Parameter( typeof( T )); // <<== Here
var memberExpression = Expression.PropertyOrField(pe /* Here */, "MyProperty");
var equalExpression = Expression.Equal( memberExpression, Expression.Constant( const ) );
var compiled = Expression.Lambda<Func<T, bool>>( equalExpression, pe ).Compile();
//                                                                ^^
//                                                                ||
//                                                             And here


Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow