Lambda and Expression.Call for an extension method
10,070
Solution 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();
Solution 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.
Solution 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
.
Solution 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.
Author by
CodeAddicted
Updated on July 29, 2022Comments
-
CodeAddicted over 1 year
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?
-
CodeAddicted almost 12 yearsThanks, I suppose I need to call GetMethod this way:
typeof(StringEx).GetMethod("Like", new[] {typeof(string)});
but how I have to inject my parameters in Expression.Call? -
CodeAddicted almost 12 yearsThanks a lot, but this throws an argument exception: Need null instance for static method, so I need some magic with BindingFlags.Static, but this is outside from my comprehension(
-
Minustar almost 12 yearsSee @Lonli-Lokli's answer below.
-
Tyler Burki almost 7 yearsThis makes sense and is exactly what I needed, thank you.