如何以表达式形式编写包含Contains的Any方法调用?
构建包含Any与Contains的表达式树步骤
要将x => x.ListOfStrings.Any(x => x.Contains("foobar"))转换为表达式树,可按以下步骤实现:
1. 定义核心参数与常量
先声明表达式所需的参数和常量:
// 外层参数:对应原始Lambda中的x(替换为实际包含ListOfStrings的实体类型) var outerParam = Expression.Parameter(typeof(YourEntity), "x"); // 内部参数:对应Any方法中的元素参数x(类型为string) var stringElementParam = Expression.Parameter(typeof(string), "x"); // 要匹配的目标字符串常量 var targetValue = Expression.Constant("foobar", typeof(string));
2. 构建内部的Contains表达式
基于你的现有实现,调整为针对string元素的表达式并封装为Lambda:
// 获取string.Contains(string)方法的MethodInfo var containsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) })!; // 构建Contains调用表达式:x.Contains("foobar") var containsCall = Expression.Call(stringElementParam, containsMethod, targetValue); // 封装为Func<string, bool>类型的Lambda表达式 var containsLambda = Expression.Lambda<Func<string, bool>>(containsCall, stringElementParam);
3. 获取Enumerable.Any的泛型方法
Any是System.Linq.Enumerable中的静态方法,需获取对应泛型重载:
// 获取接受IEnumerable<TSource>和Func<TSource, bool>的Any重载 var anyMethodDefinition = typeof(Enumerable).GetMethods() .First(m => m.Name == "Any" && m.GetParameters().Length == 2)!; // 针对string类型生成具体的泛型方法实例 var anyMethod = anyMethodDefinition.MakeGenericMethod(typeof(string));
4. 构建外层的Any调用与最终表达式
将属性访问、Any方法调用封装为最终Lambda:
// 访问外层参数的ListOfStrings属性 var listProperty = Expression.Property(outerParam, nameof(YourEntity.ListOfStrings)); // 构建Any调用表达式:x.ListOfStrings.Any(x => x.Contains("foobar")) var anyCall = Expression.Call(null, anyMethod, listProperty, containsLambda); // 封装为最终的Lambda表达式(类型为Func<YourEntity, bool>) var finalLambda = Expression.Lambda<Func<YourEntity, bool>>(anyCall, outerParam);
注意事项
- 替换
YourEntity为实际包含ListOfStrings属性的类型 - 若
ListOfStrings不是IEnumerable<string>,需同步调整泛型类型参数 - 如需处理可空字符串,可在Contains表达式中添加空值判断逻辑
内容的提问来源于stack exchange,提问作者DarkLeafyGreen
相关产品推荐
相关产品推荐

