c# - query - Cómo combinar dos lambdas
linq with lambda expression in c# (2)
El problema es que los parámetros "s" en cada lambda tienen el mismo nombre y el mismo tipo, pero son parámetros diferentes. Los parámetros tienen identidad de referencia , no identidad de valor . La simple combinación de los dos cuerpos de los árboles de expresión existentes en un tercer árbol de expresión hace que:
s => s1.Length == 5 || s2 == "somestring"
Lo que no tiene ningún sentido. Lo que quiere hacer es escribir un visitante que haga una búsqueda y reemplazo del parámetro s con un nuevo parámetro que luego usará como parámetro para la nueva expresión lambda.
Vea esta pregunta relacionada para más detalles:
Posible duplicado:
combinando dos expresiones lamba en c #
Tengo dos expresiones siguientes:
Expression<Func<string, bool>> expr1 = s => s.Length == 5;
Expression<Func<string, bool>> expr2 = s => s == "someString";
Ahora necesito combinarlos con OR. Algo como esto:
Expression.Or(expr1, expr2)
¿Hay alguna manera de hacer esto similar al código anterior como:
expr1 || expr2
Entiendo que en este ejemplo puedo combinarlo en primer lugar:
Expression<Func<string, bool>> expr = s => s.Length == 5 || s == "someString"
pero no puedo hacerlo en mi código real, ya que obtengo expr1 y expr2 como argumentos del método.
Para completar la respuesta de Eric, utilice el nuevo ExpressionVisitor
introducido en .NET 4 en lugar de un reescritor personalizado:
internal class ParameterReplacer : ExpressionVisitor {
private readonly ParameterExpression _parameter;
protected override Expression VisitParameter(ParameterExpression node) {
return base.VisitParameter(_parameter);
}
internal ParameterReplacer(ParameterExpression parameter) {
_parameter = parameter;
}
}
class Program {
static void Main(string[] args) {
Expression<Func<string, bool>> expr1 = s => s.Length == 5;
Expression<Func<string, bool>> expr2 = s => s == "someString";
var paramExpr = Expression.Parameter(typeof(string));
var exprBody = Expression.Or(expr1.Body, expr2.Body);
exprBody = (BinaryExpression) new ParameterReplacer(paramExpr).Visit(exprBody);
var finalExpr = Expression.Lambda<Func<string, bool>>(exprBody, paramExpr);
}
}