我应该如何构建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
参数,我可以使其正常工作。
由于
答案 0 :(得分: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"));
}
}
答案 1 :(得分: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"));
这比手动构建表达式树更具可读性和可维护性。
我一直对直接进入手动构建表达树的人数感到惊讶。没有必要在什么时候让编译器为你完成工作。
答案 2 :(得分:0)
我没有检查其余部分,但是如果只有枚举产生问题:
Expression.Constant(StringComparison.OrdinalIgnoreCase)
或
Expression.Constant(Enum.Parse(typeof(StringComparison), "OrdinalIgnoreCase"), typeof(Enum));
你有更多的选择。或者查看我的回答here。
编辑:忘记了paranthesis。