首页 > 后端开发 > C++ > 我如何使用C#中的操作员和或者不是运算符组合两个表达式表达式?

我如何使用C#中的操作员和或者不是运算符组合两个表达式表达式?

DDD
发布: 2025-01-31 05:56:10
原创
1002 人浏览过

>本文演示了如何使用逻辑和OR,而不是运算符组合两个类型的C#表达式。 由于参数不匹配,直接使用Expression<Func<bool>>之类的操作员是不正确的。 提出了几种方法,每个方法都解决了不同的方案。expr1 AND expr2>

方法1:简单组合(相同的参数)>

两种表达式都使用相同的参数,则直接在表达式上使用

>或Expression.AndAlso Expression.OrElse

否定同样简单:
var body = Expression.AndAlso(expr1.Body, expr2.Body);
var lambda = Expression.Lambda<Func<bool>>(body, expr1.Parameters[0]);
登录后复制
>

static Expression<Func<bool>> Not<T>(this Expression<Func<bool>> expr)
{
    return Expression.Lambda<Func<bool>>(Expression.Not(expr.Body), expr.Parameters[0]);
}
登录后复制
方法2:使用Indoke 将表达式与不同的参数组合 当表达式具有不同的参数时,可以使用

的方法来创建具有共同参数的新lambda表达式:

Invoke

static Expression<Func<bool>> AndAlso<T>(this Expression<Func<bool>> left, Expression<Func<bool>> right)
{
    var param = Expression.Parameter(typeof(T), "x");
    var body = Expression.AndAlso(Expression.Invoke(left, param), Expression.Invoke(right, param));
    var lambda = Expression.Lambda<Func<bool>>(body, param);
    return lambda;
}
登录后复制
将是相似的,用

>。 OrElseAndAlso方法3:优化组合(处理相同的和不同的参数)OrElse

>

如果参数相同,此方法智能选择了更简单的方法,否则使用>:>

Invoke方法4:使用ExpressionVisitor(.NET 4.0和更高版本)

static Expression<Func<bool>> AndAlso<T>(this Expression<Func<bool>> expr1, Expression<Func<bool>> expr2)
{
    ParameterExpression param = expr1.Parameters[0];
    if (ReferenceEquals(param, expr2.Parameters[0]))
    {
        return Expression.Lambda<Func<bool>>(Expression.AndAlso(expr1.Body, expr2.Body), param);
    }
    return Expression.Lambda<Func<bool>>(Expression.AndAlso(expr1.Body, Expression.Invoke(expr2, param)), param);
}
登录后复制
的EF-SAFE方法

对于实体框架兼容性,提供了一个可靠的解决方案:>

此方法替换了表达式中的参数参考,以确保与各种LINQ提供商的兼容性。 方法的选择取决于应用程序的特定需求和上下文,尤其是使用的LINQ提供商以及是否保证了参数一致性。 该方法为复杂的方案和实体框架集成提供了最强大的解决方案。

ExpressionVisitor

public static Expression<Func<bool>> AndAlso<T>(this Expression<Func<bool>> expr1, Expression<Func<bool>> expr2)
{
    var parameter = Expression.Parameter(typeof(T));
    var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter);
    var left = leftVisitor.Visit(expr1.Body);
    var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter);
    var right = rightVisitor.Visit(expr2.Body);
    return Expression.Lambda<Func<bool>>(Expression.AndAlso(left, right), parameter);
}

private class ReplaceExpressionVisitor : ExpressionVisitor
{
    private readonly Expression _oldValue;
    private readonly Expression _newValue;

    public ReplaceExpressionVisitor(Expression oldValue, Expression newValue)
    {
        _oldValue = oldValue;
        _newValue = newValue;
    }

    public override Expression Visit(Expression node)
    {
        if (node == _oldValue) return _newValue;
        return base.Visit(node);
    }
}
登录后复制

以上是我如何使用C#中的操作员和或者不是运算符组合两个表达式表达式?的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板