Dynamic expression on List

c# dynamic-linq expression lambda


Given the following classes

public class ClassA
    public string StringProperty { get; set; }

    public List<ClassB> List { get; set; }

public class ClassB 
    public int IntProperty { get; set; }

I Would like to dynamically create an expression like the following

x => x.StringProperty == "X" && x.List.Any( y => y.IntProperty > 1 )

No problem for the first part (x.StringProperty == "X"). For the second part I have created a member expression corresponding to x.List and now need to

  1. Create the inner lambda. To do this I need to know the type of y which is actually the same inner type of x.List
  2. Call the Any method on the x.List expression

Any hint on the first point? How do I get the type T of an IEnumerable<T>?


I have tried with the following code but it returns null unfortunately

//This expression will be x.List of my original sample 
MemberExpression expr = GetMemberExpression( property, pe );

Type innerType = expr.GetType()
                     .Where( t => t.IsGenericType == true && t.GetGenericTypeDefinition() == typeof( IEnumerable<> ) )
                     .Select( t => t.GetGenericArguments()[0] )
5/8/2017 12:25:53 PM

Accepted Answer


private static readonly MethodInfo anyT = (from x in typeof(Enumerable).GetMethods(BindingFlags.Public | BindingFlags.Static)
                                            where x.Name == nameof(Enumerable.Any) && x.IsGenericMethod
                                            let gens = x.GetGenericArguments()
                                            where gens.Length == 1
                                            let pars = x.GetParameters()
                                            where pars.Length == 2 &&
                                                pars[0].ParameterType == typeof(IEnumerable<>).MakeGenericType(gens[0]) &&
                                                pars[1].ParameterType == typeof(Func<,>).MakeGenericType(gens[0], typeof(bool))
                                            select x).Single();

// https://stackoverflow.com/a/906513/613130
private static IEnumerable<Type> GetGenericIEnumerables(Type type)
    return type.GetInterfaces()
                .Where(t => t.IsGenericType == true
                    && t.GetGenericTypeDefinition() == typeof(IEnumerable<>))
                .Select(t => t.GetGenericArguments()[0]);

Then you can:

var parX = Expression.Parameter(typeof(ClassA), "x");

var list = Expression.Property(parX, nameof(ClassA.List));

var listType = list.Type;
var baseType = GetGenericIEnumerables(listType).First();

var parY = Expression.Parameter(baseType, "y");

var eq = Expression.Equal(
    Expression.Property(parX, nameof(ClassA.StringProperty)),

var gt = Expression.GreaterThan(
    Expression.Property(parY, "IntProperty"),

var innerExpression = Expression.Lambda(gt, parY);

var any = Expression.Call(

var and = Expression.AndAlso(eq, any);

var outerExpression = Expression.Lambda<Func<ClassA, bool>>(and, parX);

var compiled = outerExpression.Compile();

var result = objs.Where(compiled).ToArray();

Note that you don't need to compile the innerExpression: the outerExpression.Compile() will do everything for you!

I'm using a modified version of getting type T from IEnumerable<T> to find the T of a IEnumerable<T>.

5/23/2017 12:34:30 PM

Related Questions

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow