Лямбда и Expression.Call для метода расширения - PullRequest
8 голосов
/ 01 декабря 2011

Мне нужно реализовать выражение для метода, как здесь:

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

К сожалению, следующий код генерирует исключение ArgumentNullException для параметра "method":

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

Что я делаю не так?

Ответы [ 5 ]

14 голосов
/ 01 декабря 2011

Попробуйте это

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();
4 голосов
/ 03 декабря 2013

Вы можете сделать это следующим образом:

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

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

Вы можете передать prop в качестве первого параметра и value в качестве второго параметра, как указано выше.

Возможно, вам потребуется получить полный запрос, прежде чем применять метод расширения.

2 голосов
/ 01 декабря 2011

Я не уверен, но вы можете получить метод расширения только из статического класса, используя отражение.Методы расширения действительно не добавляются в класс, поэтому не могут быть получены с помощью GetMethod.

1 голос
/ 01 декабря 2011

Используйте

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

есть. получить его из расширенного типа, а не из расширенного типа.

0 голосов
/ 01 декабря 2011

Если вы хотите, чтобы ваш метод расширения работал, вы должны сделать так:

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