8

我应该如何构建表达式树string.IndexOf("substring", StringComparison.OrdinalIgnoreCase)

我可以在没有第二个参数的情况下让它工作:StringComparison.OrdinalIgnoreCase. 到目前为止,这些是我的尝试:

var methodCall = typeof (string).GetMethod("IndexOf", new[] {typeof (string)});
Expression[] parms = new Expression[]{right, Expression.Constant("StringComparison.OrdinalIgnoreCase", typeof (Enum))};
var exp =  Expression.Call(left, methodCall, parms);
return exp;

也试过这个:

var methodCall = typeof (string).GetMethod(method, new[] {typeof (string)});
Expression[] parms = new Expression[]{right, Expression.Parameter(typeof(Enum) , "StringComparison.OrdinalIgnoreCase")};
var exp =  Expression.Call(left, methodCall, parms);
return exp;

OrdinalIgnoreCase请记住,如果我忽略该参数,我可以让它工作。

谢谢

4

3 回答 3

12

我怀疑有两个问题。

第一个是你获取方法的方式——你要求一个只有一个字符串参数的方法,而不是一个有两个参数的方法:

var methodCall = typeof (string).GetMethod("IndexOf",
                            new[] { typeof (string), typeof(StringComparison) });

第二个是您提供的值- 它应该是常量的实际值,而不是字符串:

Expression[] parms = new Expression[] { right, 
    Expression.Constant(StringComparison.OrdinalIgnoreCase) };

编辑:这是一个完整的工作示例:

using System;
using System.Linq.Expressions;

class Test
{
    static void Main()
    {
        var method = typeof (string).GetMethod("IndexOf",
                new[] { typeof (string), typeof(StringComparison) });

        var left = Expression.Parameter(typeof(string), "left");
        var right = Expression.Parameter(typeof(string), "right");

        Expression[] parms = new Expression[] { right, 
                Expression.Constant(StringComparison.OrdinalIgnoreCase) };

        var call = Expression.Call(left, method, parms);
        var lambda = Expression.Lambda<Func<string, string, int>>
            (call, left, right);

        var compiled = lambda.Compile();
        Console.WriteLine(compiled.Invoke("hello THERE", "lo t"));
    }
}
于 2011-08-17T07:32:18.400 回答
3

最简单的方法是通过这样的 lambda 获取它:

//the compiler will convert the lambda into an expression
Expression<Func<string, string, int>> expression = (s1, s2) => s1.IndexOf(s2, StringComparison.OrdinalIgnoreCase);
//compile the expression so we can call it
var func = expression.Compile();
//outputs 2
Console.WriteLine(func("Case Sensitive", "se sensitive"));

这比手动构建表达式树更具可读性和可维护性。

我一直对直接投入手动构建表达式树的人数感到惊讶。不需要什么时候可以让编译器为您完成工作。

于 2011-08-17T09:13:42.880 回答
0

我没有检查它的其余部分,但如果只有枚举会造成问题:

Expression.Constant(StringComparison.OrdinalIgnoreCase)

或者

Expression.Constant(Enum.Parse(typeof(StringComparison), "OrdinalIgnoreCase"), typeof(Enum));

而且你有更多的选择。或者在这里查看我的答案。

编辑:忘记括号。

于 2011-08-17T07:34:41.417 回答