你可以自己做的稍微容易。除了使用Contains
方法,其中有趣的是不支持StringComparison
作为参数传递,您可以使用IndexOf
方法。
你可以像这样实现:
public static Expression<Func<T, bool>> ContainsValue<T>(string fieldName, string val) {
var type = typeof(T);
var member = Expression.Parameter(type, "param");
var memberExpression = Expression.PropertyOrField(member, fieldName);
var targetMethod = memberExpression.Type.GetMethod("IndexOf", new Type[] { typeof(string), typeof(StringComparison) });
var methodCallExpression = Expression.Call(memberExpression, targetMethod, Expression.Constant(val), Expression.Constant(StringComparison.CurrentCultureIgnoreCase));
return Expression.Lambda<Func<T, bool>>(
Expression.AndAlso(
Expression.NotEqual(memberExpression, Expression.Constant(null)),
Expression.GreaterThanOrEqual(methodCallExpression, Expression.Constant(0))
),
member
);
}
这里的技巧是,我结合IndexOf
方法与GreaterThanOrEqual
呼叫与中端的0.1
该值给出了一个测试类下面的表达式
((param.Parameter != null) AndAlso (param.Parameter.IndexOf("test", CurrentCultureIgnoreCase) >= 0))
一个例子,你可以在这里找到在dotnetfiddle,但我还添加了完整的代码BEL流
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
public class Program
{
public static Expression<Func<T, bool>> ContainsValue<T>(string fieldName, string val) {
var type = typeof(T);
var member = Expression.Parameter(type, "param");
var memberExpression = Expression.PropertyOrField(member, fieldName);
var targetMethod = memberExpression.Type.GetMethod("IndexOf", new Type[] { typeof(string), typeof(StringComparison) });
var methodCallExpression = Expression.Call(memberExpression, targetMethod, Expression.Constant(val), Expression.Constant(StringComparison.CurrentCultureIgnoreCase));
return Expression.Lambda<Func<T, bool>>(
Expression.AndAlso(
Expression.NotEqual(memberExpression, Expression.Constant(null)),
Expression.GreaterThanOrEqual(methodCallExpression, Expression.Constant(0))
),
member
);
}
public static void Main()
{
var items = new List<Test>() {
new Test() { Parameter = "Alpha" },
new Test(),
new Test() { Parameter = "Test" },
new Test() { Parameter = "test" },
new Test() { Parameter = "TEST" },
new Test() { Parameter = "Contains test" }
};
var expr = ContainsValue<Test>("Parameter", "test");
// you can see the body here
Console.WriteLine(expr.Body);
// and the result
var results = items.Where(expr.Compile()).Select(t => t.Parameter).ToList();
Console.WriteLine("Results: {0}", string.Join(",", results));
Console.WriteLine("Total results: {0}", results.Count);
}
public class Test {
public string Parameter { get;set; }
}
}
输出:
((param.Parameter != null) AndAlso (param.Parameter.IndexOf("test", CurrentCultureIgnoreCase) >= 0))
Results: Test,test,TEST,Contains test
Total results: 4
那你试试这么远吗?你卡在哪里? – Icepickle
我一直在尝试写这样的代码来过滤任何List.it的作品,但在大写 –
私有静态表达GetPropertyExpression(的PropertyInfo道具,ParameterExpression paramExpr,常量表达式valueExpr) \t { \t \t VAR memberAcc = Expression.MakeMemberAccess(paramExpr,道具); \t \t // Console.WriteLine(memberAcc); \t \t var containsMember = typeof(string).GetMethod(“Contains”); var toLower = typeof(String).GetMethod(“ToLower”,new [] {typeof(string)}); \t \t var ttt = Expression.Call(memberAcc,containsMember,valueExpr); \t \t return Expression.Call(memberAcc,containsMember,valueExpr); \t} –