首页 > 后端开发 > C++ > 如何将逻辑表达式组合在C#表达中?

如何将逻辑表达式组合在C#表达中?

Mary-Kate Olsen
发布: 2025-01-31 05:51:08
原创
1052 人浏览过

How to Combine Logical Expressions in C# Expression?

在C#表达式中组合逻辑表达式

当您有两个Expression<Func<bool>>类型的表达式时,您可能需要使用逻辑运算符(如AND、OR或NOT)来组合它们。本文探讨实现此目标的各种方法。

相同参数实例

如果两个表达式使用相同的ParameterExpression,则组合很简单:

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]);
}
登录后复制

不同的参数实例

如果表达式使用不同的参数实例,您可以使用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;
}
登录后复制

此方法也适用于OrElseNot

通用方法

为了处理这两种情况,一种通用方法可以检测哪些参数匹配并选择合适的组合方法:

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兼容性

从.NET 4.0开始,ExpressionVisitor提供了一种构建EF兼容表达式的机制:

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);
        }
    }
登录后复制

通过选择与您的特定场景相符的方法,您可以有效地组合Expression<Func<bool>>实例中的逻辑表达式。

以上是如何将逻辑表达式组合在C#表达中?的详细内容。更多信息请关注PHP中文网其他相关文章!

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