构建字符串表达式<;Func<;T、 bool>>,忽略case

本文关键字:gt lt 忽略 bool case Func 字符串 表达式 构建 | 更新日期: 2023-09-27 18:25:00

我需要基于输入和提供的运算符构建自定义字符串表达式。然而,这些比较总是区分大小写的。我需要在忽略case的情况下进行比较。

static Expression<Func<T, bool>> GetStringExpression<T>(string field, string compareOperator, string value)
    {
        var parameterExp = Expression.Parameter(typeof(T), "type");
        var propertyExp = Expression.Property(parameterExp, field);
        MethodInfo method = typeof(string).GetMethod(compareOperator, new[] { typeof(string) });
        var someValue = Expression.Constant(value, typeof(string));
        var containsMethodExp = Expression.Call(propertyExp, method, someValue);
        return Expression.Lambda<Func<T, bool>>(containsMethodExp, parameterExp);
    }

当前代码的用法:

var expression = GetStringExpression<MyClass>("MyProperty", "Contains", "testValue");
var mylist = QueryableList.Where(expression).ToList();

当将"test"与"test"进行比较时,此比较不会返回true,这种情况也应该为true。

构建字符串表达式<;Func<;T、 bool>>,忽略case

类String上没有进行不区分大小写比较的方法,除非您传递其他参数。有很多种方法可以进行字符串比较(文化感知、操作系统感知、区分大小写),因此每次比较两个字符串时都需要使用参数。我曾研究过代码库,即使是默认的精确比较也必须明确说明,只是为了确保开发人员不会忽视他们想要哪一个。

考虑到这一点:我建议您可以停止使用"字符串"类型的字段。相反,创建一个新的类来包装一个私有的"字符串"字段,并提供您想要的功能。。。该新类可以具有不需要额外参数的Contains方法。您可以使用现有字符串API编写Contains方法来对私有字段进行操作。通过使用一个新类,无论何时进行类型反射,都将获得所需的功能。

简单的方法怎么样?

    static Expression<Func<T, bool>> GetStringExpression<T>(string field, string compareOperator, string value)
    {
        var parameterExp = Expression.Parameter(typeof(T), "type");
        var propertyExp = Expression.Property(parameterExp, field);
        MethodInfo method = typeof(string).GetMethod(compareOperator, new[] { typeof(string) });
        var someValue = Expression.Constant(value.ToLower(), typeof(string)); //mind the ToLower
        var containsMethodExp = Expression.Call(propertyExp, method, someValue);
        //and one more:
        var toStringMethod = typeof(object).GetMethod("ToString", Type.EmptyTypes);
        var toStringExp = Expression.Call(containsMethodExp, toStringMethod);
        var toLowerMethod = typeof(string).GetMethod("ToLower", Type.EmptyTypes);
        var toLowerExp = Expression.Call(toStringExp, toLowerMethod);
        return Expression.Lambda<Func<T, bool>>(toLowerExp, parameterExp);
    }

我没有测试它,但想法很简单——只需对两个值执行ToLower()。。。