I have a list of items, I want ,via expression, to filter out the items using my own custom function.
Something like this
return Items.Where(Foo)
private static bool Foo(Item item) { item.Name.Equals("...");
what i currently have
public static Expression BuildExpression(IList<Item> items)
{
Expression<Func<Item, bool>> expression = item => Foo(item);
var method = (expression.Body as MethodCallExpression)?.Method;
return Expression.Call(method, Expression.Constant(items.First());
}
this seems to work find and well for 1 item but i can't figure out how to change it to work for IList<Item>
P.s
Foo
signature can be changed if needed
In the nutshell you need to find the Enumerable.Where<TSource>(IEnumerable<TSource>, Func<TSource,Boolean>)
method. For example:
// find the Enumerable.Where with 2 parameters using reflection
var where = typeof(Enumerable).GetMethod(nameof(Enumerable.Where), BindingFlags.Public | BindingFlags.Static, new[]
{
typeof(IEnumerable<>).MakeGenericType(Type.MakeGenericMethodParameter(0)),
typeof(Func<,>).MakeGenericType(Type.MakeGenericMethodParameter(0), typeof(bool))
});
// make generic Enumerable.Where<Item>
var whereItem = where.MakeGenericMethod(typeof(Item));
// sample data
IList<Item> items = new List<Item> { new() };
// sample filter
var filter = (Item i) => true;
// create expression
var expr = Expression.Call(whereItem, Expression.Constant(items), Expression.Constant(filter));
// validate
var enumerable = Expression.Lambda<Func<IEnumerable<Item>>>(expr).Compile()();
Demo@dotnetfiddle.net with .NET Framework 4.7.1, main change:
var where = typeof(Enumerable).GetMethods(BindingFlags.Public | BindingFlags.Static)
.First(mi => mi.Name == "Where"
&& mi.GetParameters().Length == 2);
P.S.
TBH I doubt that this would be very useful for you but without having full overview of the problem it is hard to tell.