如何在C#中用表达式树动态实现空检查、ToLower与Contains调用
动态表达式构建中ToLower()调用引发ArgumentNullException的问题分析与解决
问题原因
- 方法获取错误:你尝试获取
ToLower方法时,传入了参数类型数组new[] { typeof(string) },但string.ToLower()的无参重载不需要任何参数,导致GetMethod找不到匹配的方法,返回null。后续调用Expression.Call时传入null的MethodInfo,直接触发ArgumentNullException。 - 未覆盖value的空值处理:目标表达式包含
value?.ToLower()逻辑,但你的代码未对查询值value做空值判断和大小写转换,不符合需求。
解决方案
1. 正确获取无参ToLower方法
使用Type.EmptyTypes作为参数类型数组,获取string的无参ToLower重载。
2. 完善value的空值与转换逻辑
对查询值value做空值判断,生成value?.ToLower()对应的表达式。
3. 完整构建空传播与大小写不敏感匹配逻辑
用Expression.Condition处理Item.Type的空值情况,再嵌套ToLower和Contains调用。
修正后的完整代码
var param = Expression.Parameter(typeof(Item), "i"); // 获取正确的无参ToLower方法和Contains方法 MethodInfo toLowerMethod = typeof(string).GetMethod("ToLower", Type.EmptyTypes) ?? throw new InvalidOperationException("无法获取string.ToLower()方法"); MethodInfo containsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) }) ?? throw new InvalidOperationException("无法获取string.Contains()方法"); var itemTypeMember = Expression.Property(param, "Type"); var itemTypeNullCheck = Expression.Equal(itemTypeMember, Expression.Constant(null)); // 处理查询值value的空值与ToLower转换 Expression valueExpression; if (itemType == null) // itemType为你的查询值变量 { valueExpression = Expression.Constant(null, typeof(string)); } else { valueExpression = Expression.Call(Expression.Constant(itemType), toLowerMethod); } // 构建Type?.ToLower().Contains(value?.ToLower())逻辑 var toLowerCall = Expression.Call(itemTypeMember, toLowerMethod); var containsCall = Expression.Call(toLowerCall, containsMethod, valueExpression); var itemTypeCondition = Expression.Condition(itemTypeNullCheck, Expression.Constant(false), containsCall); // 处理value为null的情况:若value是null,直接返回false(可根据业务需求调整) var valueNullCheck = Expression.Equal(valueExpression, Expression.Constant(null)); var finalCondition = Expression.Condition(valueNullCheck, Expression.Constant(false), itemTypeCondition); var lambda = Expression.Lambda<Func<Item, bool>>(finalCondition, param); Query.Where(lambda);
关键说明
- 使用
Type.EmptyTypes确保能正确匹配string.ToLower()的无参重载,避免返回null的MethodInfo。 - 对
value的空值处理完全对齐目标表达式的value?.ToLower()逻辑。 - 额外增加
value为null时的判断,避免Contains调用传入null引发异常(业务逻辑可根据需求调整,比如返回true)。
内容的提问来源于stack exchange,提问作者fingers10
相关产品推荐
相关产品推荐

