【问题标题】:Not able to compare NAN using Expression无法使用表达式比较 NAN
【发布时间】:2014-02-04 06:35:37
【问题描述】:

我正在使用表达式来比较值,并且我正在使用以下代码,

下面的方法创建 lambda 表达式。

    public static class Test
{
    public static Expression<Func<T, bool>> TransformToPredicate<T>(Expression<Func<T, double>> getvalue, double value)
    {
        System.Linq.Expressions.Expression equals = System.Linq.Expressions.Expression.Equal(getvalue.Body,
                                             System.Linq.Expressions.Expression.Constant(value));
        return System.Linq.Expressions.Expression.Lambda<Func<T, bool>>(equals, getvalue.Parameters);
    }
}

在下面的代码中,当比较 Nan 和 Nan 值时,它返回 false。使用表达式时如何克服这个问题?我需要以更通用的方式执行此操作吗?

           Employee emp = new Employee();
        emp.SickLeaveHours = double.NaN;
        Expression<Func<Employee, double>> getfunc = x => x.SickLeaveHours;
        var predicate = Test.TransformToPredicate<Employee>(getfunc, double.NaN);
        var func = predicate.Compile();
        var flag = func(emp);

当我使用非 Nan 值时,以下代码可以正常工作。

            Employee emp = new Employee();
        emp.SickLeaveHours = 10.0;
        Expression<Func<Employee, double>> getfunc = x => x.SickLeaveHours;
        var predicate = Test.TransformToPredicate<Employee>(getfunc, 10.0);
        var func = predicate.Compile();
        var flag = func(emp);

我知道 double.Nan == double.Nan 会返回 false,我们必须使用 double.IsNAN 或 value != value。但是我不确定在使用表达式时如何做到这一点。

【问题讨论】:

    标签: wpf linq lambda expression


    【解决方案1】:

    您正在按对象引用进行比较。这就是为什么你总是得到错误的回报。但是每种类型都提供Equals() 方法。为了比较两个双精度或任何两个相同的类型,您应该调用它们的Equals 函数。调用equals函数和Expression.Equal不一样。

    这是一个演示:

    var wrong =
        System.Linq.Expressions.Expression.Lambda<Func<bool>>(
        System.Linq.Expressions.Expression.Equal(System.Linq.Expressions.Expression.Constant(double.NaN),
        System.Linq.Expressions.Expression.Constant(double.NaN))).Compile();
    
    // is always false
    bool result = wrong();
    
    ConstantExpression first = System.Linq.Expressions.Expression.Constant(double.NaN, typeof(double));
    ConstantExpression second = System.Linq.Expressions.Expression.Constant(double.NaN, typeof(double));
    
    var right =
        System.Linq.Expressions.Expression.Lambda<Func<bool>>(
        System.Linq.Expressions.Expression.Call(first, first.Type.GetMethod("Equals", new[] { second.Type }), second)).Compile();
    
    // will always be true
    result = right();
    

    【讨论】:

      猜你喜欢
      • 2021-05-16
      • 2015-09-07
      • 2015-04-18
      • 1970-01-01
      • 1970-01-01
      • 2019-02-25
      • 1970-01-01
      • 2011-04-27
      • 1970-01-01
      相关资源
      最近更新 更多