Lambda and Expression.Call for extension method

I need to implement an expression for a method similar 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, the following code throws an ArgumentNullException for the method parameter:

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

What am I doing wrong?

+5
source share
5 answers

try it

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();
+12
source

You can do the following:

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

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

You can pass propas the first parameter and valueas the second parameter, as described above.

You may need to get the full request before applying the extension method.

+4
source

I'm not sure, but you can only get the extension method from a static class using reflection. Extension methods are not actually added to the class, so they cannot be obtained using GetMethod.

+2
source

Using

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

i.e., extract it from an expandable type, not from an expanded type.

+1
source

If you want your extension method to work, you must do the following:

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

All Articles