Lambda and Expression.Call for an extension method

感情迁移 提交于 2019-12-19 17:38:51

问题


I need to implement an expression for a method like here:

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

But for my extension method:

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

Unfortunately, next code throws an ArgumentNullException for a parameter "method":

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

What I'm doing wrong?


回答1:


Try this

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<bool>) Expression.Lambda(comparer).Compile();
bool isEquals = vvv.Invoke();



回答2:


You can do like this:

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

comparer = Expression.Call(null, like, prop, value);

You can pass prop as first parameter and value as second parameter like above.

Maybe you will need to get a complete query before apply an extension method.




回答3:


I am not sure, but you can only get an extension method from the static class using reflection. Extension methods are not truly added to the class, therefore can't be retrieved with GetMethod.




回答4:


Use

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

ie. retrieve it from the extending type, not from the extended type.




回答5:


If you want to get your extension method worked you must do like this:

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


来源:https://stackoverflow.com/questions/8337774/lambda-and-expression-call-for-an-extension-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!