我正在使用表达式比较值,并且我正在使用以下代码,
下面的方法创建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值进行比较时,它返回false。使用Axpressioon时如何克服这一点?我需要以更通用的方式执行此操作?
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。但是我不确定在使用表达式时该怎么做。
您是通过对象引用进行比较。这就是为什么您总是会返回错误的原因。但是,每种类型都提供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();