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