Например, у меня есть класс с некоторым свойством:Как вызвать метод с экземпляром с помощью Expression
public class SomeClass
{
public Version Version { get; set; }
}
И у меня есть список этого типа с данными выборки:
var list = new List<SomeClass>();
for (var i = 0; i < 1000; i++)
{
list.Add(new SomeClass
{
Version = new Version(i, i/2, i/3, i/4),
});
}
Я хочу написать метод, который фильтрует по версии с использованием метода Version.Equals:
var filterValue = new Version(12, 6, 4, 3);
var modelType = typeof(SomeClass);
var propertyType = typeof(Version);
var arg = Expression.Parameter(modelType, "x");
var property = Expression.Property(arg, "Version");
var value = Expression.Convert(Expression.Constant(filterValue), propertyType);
var versionEqualsMethod = typeof(Version).GetMethod("Equals", new[] { typeof(Version) });
/////////
Expression inst = null; // <-- ???
/////////
var expr = Expression.Call(inst, versionEqualsMethod, property, value);
var delegateType = typeof(Func<,>).MakeGenericType(modelType, typeof(bool));
var delegateValue = Expression.Lambda(delegateType, expr, arg).Compile();
var genericMethod =
typeof(Enumerable).GetMethods()
.First(
method =>
method.Name == "Where" && method.IsGenericMethodDefinition
&& method.GetGenericArguments().Length == 1 && method.GetParameters().Length == 2)
.MakeGenericMethod(modelType);
var result = genericMethod.Invoke(null, new object[] { list, delegateValue });
Что я могу использовать в качестве примера в выражении .Вызов?
UPDATE
Решение:
var expr = Expression.Call(property, versionEqualsMethod, value);
Вы хотите протестировать или узнать выражение? или ваш пример - ваш случай? – Amir
Я хочу написать расширение для фильтрации IEnumerable. Это просто случай использования Expression.Call с экземпляром. –
Vitone
Почему бы не использовать отражение? Было бы намного проще. См. Мой ответ ниже. –