You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中用表达式树动态实现空检查、ToLower与Contains调用

动态表达式构建中ToLower()调用引发ArgumentNullException的问题分析与解决

问题原因

  1. 方法获取错误:你尝试获取ToLower方法时,传入了参数类型数组new[] { typeof(string) },但string.ToLower()的无参重载不需要任何参数,导致GetMethod找不到匹配的方法,返回null。后续调用Expression.Call时传入null的MethodInfo,直接触发ArgumentNullException。
  2. 未覆盖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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 12:55:13