1

从昨天开始,我一直在自学表达式树,但在比较两个字符串值时遇到了问题。我做了这个测试用例失败并出现错误:

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. 这就是使用比较方法的原因。

我确信它很简单,我已经将我的代码归结为这个简单的测试用例。有人看到我哪里出错了吗?

4

2 回答 2

12

这是您的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());
    }
}
于 2012-05-10T18:31:38.747 回答
2

我试图做与 lambda where 子句(LINQ to SQL)类似的事情,并且由于各种搜索让我登陆了这个页面,所以我将在这里分享这样的解决方案,以防它帮助其他登陆这里的人。

当您使用 Compare 的通用表达式简化您正在做的事情时,这是最简单的。

    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);
    }

可以使用女巫,例如

public static IQueryable<T> ApplyFilters<T>(this IQueryable<T> query, List<GridFilters> gridFilters)
{
    // foreach filter
        // Get property (propertyInfo)
        // Get Value(s)
        // Apply Filter
        query = query.Where(PropertyLessThanOrEqualString<T, string>(propertyInfo, value1));

    // ...

    return query;
}

如果您有一个需要应用的用户选择的过滤器列表,这将很有用,其中值和运算符都可以选择。(开始于、包含、介于范围之间)

于 2016-04-22T18:15:46.367 回答