Search code examples
c#lambdaexpression-trees

How to create expression tree returning restricted set of properties, based on convention?


I need to create an expression tree returning Expression<Func<TDataStructure, Double[]>> expression. Tricky part about it, is that TDataStructure is generic what implies, that each passed class contains different set of properties. I need to get properties of type Double? and names starting with specific string, like "output".

Simple example case (concrete class):

Expression<Func<ConcreteDataStructure, Double[]>> expression =
    structure => new Double[] {
         structure.inputProperty1.Value,
         structure.outputProperty1.Value,
         structure.outputProperty2.Value
    };

where: structure.inputProperty1.Value, structure.outputProperty1.Value, structure.outputProperty2.Value are of type Double?

My case:

  1. I do not know how many properties of type Double? are in TDataStructure

  2. I need to get only these of type Double?, starting with "output"

  3. Expression will be used in IQueryable<TDataStructure> Select method for projection of each sequence element into new form.


Solution

  • Try this:

    public static Expression<Func<T, Double[]>> BuildExpression<T>()
    {
        ParameterExpression param = Expression.Parameter(typeof(T));
        Expression[] array = typeof(T).GetProperties()
            .Where(p => p.Name.StartsWith("input") || p.Name.StartsWith("output"))
            .OrderBy(p => p.Name)
            .Select(p => (Expression)Expression.Property(Expression.Property(param, p), "Value"))
            .ToArray();
    
        Expression body = Expression.NewArrayInit(typeof(Double), array);
    
        return Expression.Lambda<Func<T, Double[]>>(body, param);
    }