C# 构建字符串表达式<;Func<;T、 布尔>>,忽略案例
我需要根据输入和提供的运算符构建自定义字符串表达式。然而,这些比较总是区分大小写的。我需要在忽略案例的情况下进行比较C# 构建字符串表达式<;Func<;T、 布尔>>,忽略案例,c#,expression,C#,Expression,我需要根据输入和提供的运算符构建自定义字符串表达式。然而,这些比较总是区分大小写的。我需要在忽略案例的情况下进行比较 static Expression<Func<T, bool>> GetStringExpression<T>(string field, string compareOperator, string value) { var parameterExp = Expression.Parameter(typeof(T),
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);
}
静态表达式GetStringExpression(字符串字段、字符串比较运算符、字符串值)
{
var parameterExp=表达式参数(typeof(T),“type”);
var propertyExp=Expression.Property(参数exp,字段);
MethodInfo method=typeof(string).GetMethod(compareOperator,new[]{typeof(string)});
var someValue=Expression.Constant(value,typeof(string));
var containsMethodExp=Expression.Call(propertyExp,method,someValue);
返回表达式.Lambda(containsMethodex,parameterExp);
}
当前代码的用法:
var expression = GetStringExpression<MyClass>("MyProperty", "Contains", "testValue");
var mylist = QueryableList.Where(expression).ToList();
var expression=GetStringExpression(“MyProperty”、“Contains”、“testValue”);
var mylist=QueryableList.Where(表达式).ToList();
当比较“test”和“test”时,这种比较不会返回true,这种情况也应该是true。那么简单的方法呢
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);
}
静态表达式GetStringExpression(字符串字段、字符串比较运算符、字符串值)
{
var parameterExp=表达式参数(typeof(T),“type”);
var propertyExp=Expression.Property(参数exp,字段);
MethodInfo method=typeof(string).GetMethod(compareOperator,new[]{typeof(string)});
var someValue=Expression.Constant(value.ToLower(),typeof(string));//注意ToLower
var containsMethodExp=Expression.Call(propertyExp,method,someValue);
//还有一点:
var-toStringMethod=typeof(object.GetMethod)(“ToString”,Type.EmptyTypes);
var-toStringExp=Expression.Call(containsMethodExp,toStringMethod);
var toLowerMethod=typeof(string.GetMethod)(“ToLower”,Type.EmptyTypes);
var tolowerepp=Expression.Call(toStringExp,toLowerMethod);
返回表达式.Lambda(toloweresp,parameterExp);
}
我没有对它进行测试,但想法很简单-只需对两个值执行
ToLower()
。除非传递其他参数,否则类字符串上没有不区分大小写的比较方法。有很多种方法可以进行字符串比较(文化意识、操作系统意识、区分大小写),因此每次比较两个字符串时都需要使用参数。我曾经在代码库上工作过,即使默认的精确比较也必须明确说明,以确保开发人员不会忽略考虑他们想要哪一个
鉴于此:我建议您停止使用“string”类型的字段。相反,创建一个新类来包装一个私有“字符串”字段并提供您想要的功能。。。这个新类可以有一个不需要额外参数的Contains方法。您可以使用现有的字符串API编写包含方法的代码,以对私有字段进行操作。通过使用新类,无论何时进行类型反射,您都将获得所需的功能。编辑的问题,比较忽略字符串大小写您能否给出一个可能的
比较运算符的示例?您的问题令人困惑-比较通常返回int
,而不是bool
。另外,compareOperator
必须是一个在代码中似乎不符合上下文的String
类型方法的名称。您必须打开compareOperator
以确定适当的重载和要传递的适当类型(stringcomparation
,StringComparer
等)。你到底想做什么?添加了用法代码,就是传入一个过滤器列表并动态创建一个表达式在我的列表上执行。你让方法的使用者传入任意方法名称(如compareOperator
参数),这很容易出错,而且不太友好。您最好创建一个enum
,它将表示您要支持的方法,然后在值上切换以确定正确的方法重载和参数。另外,为什么要生成一个表达式
,而不仅仅是一个泛型委托?是否会有一些LINQ提供程序来解释这些表达式?调用ToLower假设类型实际上是一个字符串。注意,“value”参数用于构造其他类型:var someValue=Expression.Constant(value,typeof(string));因此,对value属性使用任何其他方法都不起作用。您所说的是字段
,而不是值
(这是一个字符串参数),您是正确的。只需在调用ToLower
之前添加对ToString
的调用。接得好!:)是的,但我认为这篇文章想对“someValue”进行不区分大小写的比较——也就是说,如果T恰好是字符串,那么做一些特殊的事情,否则,就完全按照代码现在所做的去做。typeof(object).GetMethod(“ToLower”)
将抛出,因为还有一个overload@srm顺便说一句,我认为您的注释是错误的-T只是基本类型参数,而field
是其中一个字段的名称,在该字段上进行比较。