构建检查对象两个属性相等的Expression表达式时返回false的问题
解决Expression构建判断属性相等Lambda返回False的问题
嘿,我完全懂你现在的困扰——用Expression树写判断对象两个int属性是否相等的逻辑,结果一直返回false,大概率是你在构建表达式的时候没把属性取值和输入对象正确绑定,或者Lambda的结构没搭对。我来一步步给你捋清楚正确的做法:
先明确核心逻辑
我们要构建的Lambda本质上是这样的:obj => obj.PropA == obj.PropB,所以整个Expression树需要包含这几个部分:
- 输入参数(也就是那个带两个int属性的对象)
- 从参数上获取两个属性的表达式
- 两个属性值的相等比较表达式
- 把这些包装成完整的Lambda表达式
举个具体的实现例子
假设你的目标类是这样的:
public class MyDataObject { public int FirstIntProp { get; set; } public int SecondIntProp { get; set; } }
那正确构建Expression的代码应该是这样的:
// 1. 定义Lambda的输入参数表达式 ParameterExpression inputParam = Expression.Parameter(typeof(MyDataObject), "obj"); // 2. 从参数上获取两个属性的表达式(关键:必须基于同一个inputParam) MemberExpression firstPropExpr = Expression.Property(inputParam, nameof(MyDataObject.FirstIntProp)); MemberExpression secondPropExpr = Expression.Property(inputParam, nameof(MyDataObject.SecondIntProp)); // 3. 构建两个属性的相等比较表达式 BinaryExpression equalCheckExpr = Expression.Equal(firstPropExpr, secondPropExpr); // 4. 把比较表达式包装成完整的Lambda,并指定参数 Expression<Func<MyDataObject, bool>> equalLambda = Expression.Lambda<Func<MyDataObject, bool>>(equalCheckExpr, inputParam); // 5. 编译成可执行的委托(如果需要直接调用的话) Func<MyDataObject, bool> checkEqual = equalLambda.Compile();
测试一下效果
var testObj1 = new MyDataObject { FirstIntProp = 10, SecondIntProp = 10 }; var testObj2 = new MyDataObject { FirstIntProp = 5, SecondIntProp = 8 }; Console.WriteLine(checkEqual(testObj1)); // 输出 True Console.WriteLine(checkEqual(testObj2)); // 输出 False
你可能踩的坑
- 属性表达式没绑定到输入参数:如果你的属性表达式不是基于
inputParam创建的,而是直接用了其他方式(比如硬编码的常量或者无关的表达式),那肯定会返回错误的结果。 - Lambda参数不匹配:构建
Expression.Lambda的时候,一定要把定义的inputParam传进去,否则Lambda无法正确接收输入对象。 - 属性名称写错:如果
Expression.Property里的属性名和类里的实际名称不一致,会导致获取不到正确的属性值,自然一直返回false。
通用化的方法(适配任意带两个int属性的类)
如果你想写一个通用方法,支持任意类型的对象,只需要传入属性名称:
public static Func<T, bool> CreateIntPropertyEqualityChecker<T>(string firstPropName, string secondPropName) { var inputParam = Expression.Parameter(typeof(T), "obj"); // 获取两个属性的表达式 var firstProp = Expression.Property(inputParam, firstPropName); var secondProp = Expression.Property(inputParam, secondPropName); // 可选:校验属性类型是否为int if (firstProp.Type != typeof(int) || secondProp.Type != typeof(int)) throw new ArgumentException("Both properties must be of type int."); // 构建比较并包装成Lambda var equalExpr = Expression.Equal(firstProp, secondProp); var lambda = Expression.Lambda<Func<T, bool>>(equalExpr, inputParam); return lambda.Compile(); }
这样调用的时候就很灵活了:
var checker = CreateIntPropertyEqualityChecker<MyDataObject>(nameof(MyDataObject.FirstIntProp), nameof(MyDataObject.SecondIntProp));
内容的提问来源于stack exchange,提问作者mshwf
相关产品推荐
相关产品推荐

