Expression.Lambda.Compile()无法比较参数字符串值

时间:2014-06-30 16:03:12

标签: c# .net lambda expression

基本上我在运行时编译表达式然后我用DynamicInvoke方法调用它们都应该返回布尔值,但问题是当存在字符串比较时,它会失败。假设SomeProp的{x.SomeProp == "value"}值的表达式为"value",但是当我执行该表达式上的DynamicInvoke时,将相应的对象传递给它并将返回值强制转换为bool I得到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\")"

1 个答案:

答案 0 :(得分:0)

您在stringobject类型之间存在相等比较,因为Expression.Constant会返回类型为object的表达式,因为ChangeType也是如此。这意味着您可以像参考someString == (object)"..."一样进行参考比较。

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


DynamicInvoke比直接调用慢,因为它在每次调用时都使用反射。如果您打算使用此功能,请编译为Func<object>并在编译方法中进行强制转换,以将object参数转换为正确的类型。