Lambda和Expression.Call用于扩展方法

我需要为这样的方法实现一个表达式:

var prop = Expression.Property(someItem, "Name"); var value = Expression.Constant(someConstant); var contains = typeof(string).GetMethod("Contains", new[] {typeof(string)}); var expression = Expression.Call(prop, contains, value); 

但对于我的扩展方法:

 public static class StringEx { public static bool Like(this string a, string b) { return a.ToLower().Contains(b.ToLower()); } } 

不幸的是,下一个代码为参数“method”抛出了ArgumentNullException:

 var like = typeof(string).GetMethod("Like", new[] {typeof(string)}); comparer = Expression.Call(prop, like, value); 

我做错了什么?

试试这个

 public class Person { public string Name { get; set; } } public static class StringEx { public static bool Like(this string a, string b) { return a.ToLower().Contains(b.ToLower()); } } Person p = new Person(){Name = "Me"}; var prop = Expression.Property(Expression.Constant(p), "Name"); var value = Expression.Constant("me"); var like = typeof(StringEx).GetMethod("Like", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); var comparer = Expression.Call(null, like, prop, value ); var vvv = (Func) Expression.Lambda(comparer).Compile(); bool isEquals = vvv.Invoke(); 

你可以这样做:

 var like = typeof(StringEx).GetMethod("Like", new[] {typeof(string), typeof(string)}); comparer = Expression.Call(null, like, prop, value); 

您可以将prop作为第一个参数传递,将value作为第二个参数传递给上面。

在应用扩展方法之前,您可能需要获得完整的查询。

我不确定,但是你只能使用reflection从静态类中获取扩展方法。 扩展方法没有真正添加到类中,因此无法使用GetMethod检索。

使用

 var like = typeof(StringEx).GetMethod("Like", new[] {typeof(string),typeof(string)}); 

即。 从扩展类型中检索它,而不是从扩展类型中检索它。

如果你想让你的扩展方法有效,你必须这样做:

 string str = "some string"; str.Like("second string");