2016-07-28 2 views
3

Мне нужно создать дерево выражений, возвращающее Expression<Func<TDataStructure, Double[]>> expression. Обманная часть об этом заключается в том, что TDataStructure является общим, что подразумевает, что каждый прошедший класс содержит разные свойства. Мне нужно получить свойства типа Double? и имена, начинающиеся с определенной строки, например "output".Как создать дерево выражений, возвращающее ограниченный набор свойств на основе соглашения?

Простой пример случай (класс бетона):

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

где: structure.inputProperty1.Value, structure.outputProperty1.Value, structure.outputProperty2.Value имеют тип Double?

Мой случай:

  1. Я не знаю, сколько свойства типа Double? в TDataStructure

  2. мне нужно получить только эти типа Double?, начиная с "output"

  3. Выражение будет использоваться в методе IQueryable<TDataStructure> Select для проектирования каждого элемента последовательности в новую форму.

+0

И 1 и 2 могут быть решены с помощью отражения: смотреть на 'Type.GetProperties()' или 'TypeInfo.GetProperties()' (в зависимости от отражения API вы используете). –

+0

Это, я знаю. Но я не знаю, как использовать его в Expression. вар свойства = TypeOf (TrainingData) .GetProperties() .где (свойство => property.PropertyType == TypeOf (Double) && property.Name.ToLowerInvariant() StartsWith ("продукт")?!.); – Marek

+0

@Marek: Правильно, поэтому, как только вы найдете свойства, которые хотите использовать, вы можете использовать выражение Expression.Property для создания выражения для каждого из этих свойств ... –

ответ

3

Попробуйте это:

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); 
} 
+0

Это решило! – Marek

1

Я хотел бы предложить следующее:

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); 
} 

Если все в порядке с возможным нулем-рефами, в случае, если ваш double? не имеет никакого значения.

 Смежные вопросы

  • Нет связанных вопросов^_^