You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将字符串转换为C#条件运算符并生成Func<>委托?

C# 字符串运算符转条件委托实现方案

1. 定义Filter实体类

首先定义承载过滤规则的Filter类,包含运算符、比较值和目标属性名:

public class Filter
{
    // 条件运算符字符串(如"=="、"greaterthan"、"contains")
    public string FilterOperator { get; set; }
    // 比较值,支持int、double、bool、string等类型
    public object Value { get; set; }
    // 需要过滤的目标对象属性名称
    public string TargetProperty { get; set; }
}

2. 实现运算符转换与条件委托构建

通过表达式树动态生成条件委托,统一管理字符串到C#运算符的映射:

using System;
using System.Linq.Expressions;
using System.Collections.Generic;

public static class FilterConditionBuilder
{
    // 字符串运算符到表达式树操作的映射表
    private static readonly Dictionary<string, Func<Expression, Expression, Expression>> _operatorMappings = new()
    {
        { "==", Expression.Equal },
        { "!=", Expression.NotEqual },
        { "greaterthan", Expression.GreaterThan },
        { "greaterthanequal", Expression.GreaterThanOrEqual },
        { "lessthan", Expression.LessThan },
        { "lessthanequal", Expression.LessThanOrEqual },
        { "contains", (left, right) => Expression.Call(left, typeof(string).GetMethod("Contains", new[] { typeof(string) }), right) }
    };

    // 生成单个Filter对应的条件委托
    public static Func<T, bool> BuildCondition<T>(Filter filter)
    {
        var parameter = Expression.Parameter(typeof(T), "obj");
        var propertyExpr = Expression.Property(parameter, filter.TargetProperty);
        
        // 将比较值转换为目标属性的类型,确保类型匹配
        var convertedValue = Convert.ChangeType(filter.Value, propertyExpr.Type);
        var valueExpr = Expression.Constant(convertedValue, propertyExpr.Type);

        if (!_operatorMappings.TryGetValue(filter.FilterOperator.ToLower(), out var exprBuilder))
        {
            throw new NotSupportedException($"不支持的运算符:{filter.FilterOperator}");
        }

        // 构建比较表达式并编译为委托
        var conditionExpr = exprBuilder(propertyExpr, valueExpr);
        return Expression.Lambda<Func<T, bool>>(conditionExpr, parameter).Compile();
    }

    // 组合多个Filter条件,支持and/or逻辑
    public static Func<T, bool> CombineConditions<T>(IEnumerable<Filter> filters, string combineOperator = "and")
    {
        var conditionList = filters.Select(f => BuildCondition<T>(f)).ToList();
        if (!conditionList.Any())
            return _ => true;

        var parameter = Expression.Parameter(typeof(T), "obj");
        Expression combinedBody = null;

        foreach (var condition in conditionList)
        {
            var conditionBody = Expression.Invoke(Expression.Constant(condition), parameter);
            
            combinedBody = combinedBody == null 
                ? conditionBody 
                : combineOperator.ToLower() switch
                {
                    "and" => Expression.AndAlso(combinedBody, conditionBody),
                    "or" => Expression.OrElse(combinedBody, conditionBody),
                    _ => throw new NotSupportedException($"不支持的组合运算符:{combineOperator}")
                };
        }

        return Expression.Lambda<Func<T, bool>>(combinedBody, parameter).Compile();
    }
}

3. 示例用法

假设我们有一个User类,使用上述工具类构建过滤条件:

public class User
{
    public string Name { get; set; }
    public int Age { get; set; }
    public double Score { get; set; }
    public bool IsActive { get; set; }
}

// 单个条件示例
var nameFilter = new Filter
{
    FilterOperator = "contains",
    Value = "John",
    TargetProperty = nameof(User.Name)
};
var nameCondition = FilterConditionBuilder.BuildCondition<User>(nameFilter);

var user1 = new User { Name = "John Doe" };
Console.WriteLine(nameCondition(user1)); // 输出: True

// 多条件组合示例
var filters = new List<Filter>
{
    new Filter { FilterOperator = "greaterthanequal", Value = 18, TargetProperty = nameof(User.Age) },
    new Filter { FilterOperator = "==", Value = true, TargetProperty = nameof(User.IsActive) }
};
var combinedCondition = FilterConditionBuilder.CombineConditions<User>(filters, "and");

var user2 = new User { Age = 25, IsActive = true };
Console.WriteLine(combinedCondition(user2)); // 输出: True
var user3 = new User { Age = 16, IsActive = true };
Console.WriteLine(combinedCondition(user3)); // 输出: False

核心优势

  • 类型安全:通过表达式树和类型转换,避免硬编码不同类型的比较逻辑
  • 扩展性强:新增运算符只需在映射表中添加对应规则即可
  • 灵活组合:支持多条件的and/or逻辑拼接,满足复杂过滤需求

内容的提问来源于stack exchange,提问作者TheBoubou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 05:10:37