首页 > 后端开发 > C++ > 如何结合LINQ中类型的逻辑表达式?

如何结合LINQ中类型的逻辑表达式?

DDD
发布: 2025-01-31 06:01:09
原创
561 人浏览过

How to Combine Logical Expressions of Type `Expression` in LINQ?

在LINQ中组合Expression<Func<bool>>类型的逻辑表达式

LINQ经常使用表达式,表达式是lambda表达式的表示形式。在处理表达式时,经常需要组合两个逻辑表达式,例如AND、OR或NOT。

例如,考虑以下两个表达式:

<code class="language-csharp">Expression<Func<bool>> expr1;
Expression<Func<bool>> expr2;</code>
登录后复制

我们可能希望组合这些表达式以获得相同类型的新的表达式:

<code class="language-csharp">// 示例用法(原样无效)
Expression<Func<bool>> andExpression = expr1 AND expr2;</code>
登录后复制

组合具有相同参数的表达式

如果expr1expr2都使用相同的参数,则操作很简单:

<code class="language-csharp">var body = Expression.AndAlso(expr1.Body, expr2.Body);
var lambda = Expression.Lambda<Func<bool>>(body, expr1.Parameters[0]);</code>
登录后复制

组合具有不同参数的表达式

但是,如果表达式使用不同的参数,我们必须注意如何组合它们。使用Invoke可以实现这一点:

<code class="language-csharp">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;
}</code>
登录后复制

通用方法

以下代码片段提供了一种通用方法,用于确定组合表达式的最合适方法:

<code class="language-csharp">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);
}</code>
登录后复制

其他注意事项

在.NET 4.0及更高版本中,可以使用ExpressionVisitor类创建EF安全的表达式:

<code class="language-csharp">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);
}</code>
登录后复制

This revised output maintains the original image and provides a more concise and readable explanation of the code snippets. The code examples are also formatted for better readability.

以上是如何结合LINQ中类型的逻辑表达式?的详细内容。更多信息请关注PHP中文网其他相关文章!

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