【问题标题】:Expression.Lambda.Compile() cannot comparing parameter string valuesExpression.Lambda.Compile() 无法比较参数字符串值
【发布时间】:2014-06-30 16:03:11
【问题描述】:

基本上我在运行时编译表达式,然后我用DynamicInvoke 方法调用它们,它们都应该返回布尔值,但问题是当进行字符串比较时,它会失败。假设像 {x.SomeProp == "value"} 这样的表达式 SomeProp 的值是 "value" 但是当我在该表达式上执行 DynamicInvoke 时,将适当的对象传递给它并将返回值转换为 bool 我得到 false 作为答案。

这是我用来构建表达式的代码

public static Expression BuildExpression(string propName, Operator op, object value, ParameterExpression paramExp)
{
    var expressionType = new ExpressionType();
    var leftOperand = CreateExpression(paramExp, propName);

    var rightOperand = leftOperand.Type.BaseType == typeof(Enum) ? 
        Expression.Constant(Enum.Parse(leftOperand.Type, value.ToString(), true)) : Expression.Constant(Convert.ChangeType(value, leftOperand.Type));

    var fieldInfo = expressionType.GetType().GetFields(Enum.GetName(typeof(Operator), op));
    var expressionTypeValue = (ExpressionType)fieldInfo.GetValue(op);

    var binaryExpression = Expression.MakeBinary(expressionType, leftOperand, rightOperand);

    returnExpression;
}

private static Expression CreateExpression(ParameterExpression type, string propName)
{
    Expression body = type;
    body = Expression.PropertyOrField(body, propName);

    return body;
}

paramExp基本上就是这个

var param = Expression.Parameter(someObjectType, "x");

现在这段代码在构建表达式方面做得很好,那么我做

Expression.Lambda(exp, param).Compile();

在上面,然后

copiledExp.DynamicInvoke(someObj);

比较intdoublefloatdecimal 甚至enum 值时它工作正常,但最近我遇到了比较字符串的问题。它在任何表达式上都返回 false

这是正在构建的表达式的视图。我的意思是,这是ToString() 方法返回的

"(x.SomeStringProp == \"stringValue\")"

【问题讨论】:

标签: c# .net lambda expression


【解决方案1】:

您在stringobject 类型之间进行的相等比较,因为Expression.Constant 会返回一个对象类型的表达式,因为ChangeType 也是如此。这意味着您将获得参考比较,就像您编写了someString == (object)"..."

您必须构建一个调用string.Equals 或任何其他等效方法的表达式。或者,您将常量设为string 类型,以便选择string 的重载相等运算符。


DynamicInvoke 比直接调用慢,因为它在每次调用时都使用反射。如果你想用这个来提高性能,编译成 Func<object> 并在编译的方法中进行强制转换,将 object 参数转换为正确的类型。

【讨论】:

  • String 实现了自己的相等运算符 ==,它调用 String.Equals。它不是参考比较。
  • @user957902 表达式树等于不使用重载运算符。这不是 C#。
  • Expression.Equal 的文档说它将在正确的情况下使用重载的相等运算符。如果将两个字符串常量表达式传递给 Expression.Equal,您将获得 {Boolean op_Equality(System.String, System.String)} 的实现方法
  • 我不知道。然后,他的问题是Expression.Constant 给他返回了一个对象类型的表达式。编辑。
猜你喜欢
  • 1970-01-01
  • 2013-10-28
  • 1970-01-01
  • 2022-01-16
  • 1970-01-01
  • 2018-08-14
  • 1970-01-01
  • 1970-01-01
  • 2016-04-27
相关资源
最近更新 更多