在Expression中使用string.Compare(a,b)

时间:2012-05-10 18:29:46

标签: c# expression expression-trees

我从昨天开始自学 Expression Trees ,我在比较两个字符串值时遇到了问题。我已经使这个测试用例失败并出现错误:

No method 'Compare' on type 'System.String' is compatible with the supplied arguments.

left = Expression.Call(

的运行时失败
Type type = typeof(string);
Expression left, right;
left = Expression.Constant("1", type);
right = Expression.Constant("2", type);
// fails at run-time on the next statement
left = Expression.Call(
    typeof(string),
    "Compare",
    new Type[] { type, type },
    new Expression[] { left, right });
right = Expression.Constant(0, typeof(int));

我将使用由此产生的左和右在Expression.Equal, LessThan, LessThanOrEqual, GreaterThan or GreaterThanOrEqual中。这就是Compare方法的原因。

我确信这很简单,我已将我的代码简化为这个简单的测试用例。谁知道我哪里出错了?

2 个答案:

答案 0 :(得分:9)

这是Expression.Call代码中的问题:

new Type[] { type, type },

那是试图调用string.Compare<string, string> - 它们是泛型参数,而不是普通参数的类型。鉴于它是一种非泛型方法,只需在此处使用null。

简短但完整的计划:

using System;
using System.Linq.Expressions;

class Test
{
    static void Main()
    {
        var left = Expression.Constant("1", typeof(string));
        var right = Expression.Constant("2", typeof(string));
        var compare = Expression.Call(typeof(string),
                                      "Compare",
                                      null,
                                      new[] { left, right });
        var compiled = Expression.Lambda<Func<int>>(compare).Compile();
        Console.WriteLine(compiled());
    }
}

答案 1 :(得分:2)

我试图做一个类似于lambda where子句( LINQ to SQL ),并且因为各种搜索让我登陆这个页面,所以我将在这里分享这样的解决方案以防万一它可以帮助那些降落在这里的人。

使用比较的通用表达式简化您正在执行的操作时,这是最简单的。

public SubscriptionToken Subscribe(Action<TPayload> action)

然后你可以像任何其他

一样使用这个表达式
    public static Expression CompareLessThanOrEqualTo(Expression e1, Expression e2)
    {
        var compare = Expression.Call(typeof(string),
                           "Compare",
                           null,
                           new[] { e1, e2 });

        return Expression.LessThanOrEqual(compare, Expression.Constant(0));
    }

可以使用女巫,如

    public static Expression<Func<TypeOfParent, bool>> PropertyLessThanOrEqualString<TypeOfParent, String>(PropertyInfo property, String value)
    {
        var parent = Expression.Parameter(typeof(TypeOfParent));
        var expressionBody = CompareLessThanOrEqualTo(Expression.Property(parent, property), Expression.Constant(value));
        return Expression.Lambda<Func<TypeOfParent, bool>>(expressionBody, parent);
    }

如果您有一个需要应用的用户选择的过滤器列表,则可以选择值和运算符。 (开头,包含,范围之间)