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

构建检查对象两个属性相等的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

你可能踩的坑

  1. 属性表达式没绑定到输入参数:如果你的属性表达式不是基于inputParam创建的,而是直接用了其他方式(比如硬编码的常量或者无关的表达式),那肯定会返回错误的结果。
  2. Lambda参数不匹配:构建Expression.Lambda的时候,一定要把定义的inputParam传进去,否则Lambda无法正确接收输入对象。
  3. 属性名称写错:如果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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:28:47