Reputation: 33
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:
I do not know how many properties of type Double?
are in TDataStructure
I need to get only these of type Double?
, starting with "output"
Expression will be used in IQueryable<TDataStructure> Select
method for projection of each sequence element into new form.
Upvotes: 3
Views: 75
Reputation: 16150
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);
}
Upvotes: 3
Reputation: 4408
I'd suggest this:
static Expression<Func<T, double[]>> DoublePropertiesSelector<T>()
{
var data = Expression.Parameter(typeof(T));
return Expression.Lambda<Func<T, double[]>>(
Expression.NewArrayInit(typeof(double),
from property in typeof(T).GetProperties()
where property.PropertyType == typeof(double?)
select Expression.Property(Expression.Property(data, property.Name), "Value")),
data);
}
If you are okay with possible null-refs, in case your double?
has no value.
Upvotes: 1