从Expression对象中找到的多个属性对象中获取PropertyInfo

时间:2016-03-07 16:12:58

标签: linq linq-expressions

我需要更改一个接受一个Expression的函数,其中包含一个属性,并且至少可以使用2个属性。

我有以下包含嵌套ElementHelper类

的基类
public class DomainObjectViewModel<TModel> where TModel : DomainObject
{

    public class ElementHelper
    {
        public static void Create<T1>(TModel model, Expression<Func<TModel, T1>> expression)
        {
            var getPropertyInfo = GetPropertyInfo(expression);
            //Do cool stuff
        }
        private static PropertyInfo GetPropertyInfo<T1>(Expression<Func<TModel, T1>> propertyExpression)
        {
            return (PropertyInfo)((MemberExpression)propertyExpression.Body).Member;
        }
    }
}

-ElementHelper类包含一个Create函数,该函数获取表达式的propertyInfo,只有在表达式中传递一个属性时才有效。

然后我有以下继承的类,它在构造函数中使用了辅助函数。

public class ProductViewModel : DomainObjectViewModel<ProductEditViewModel>
{
    public ProductViewModel(ProductEditViewModel model)
    {
        //It works for one property in the Expression
        ElementHelper.Create(model, x => x.LaunchDate);
        //Give the ability to pass multiple paramenters in the expression  
        ElementHelper.Create(model, x => new { x.LaunchDate, x.ApplyLaunchDateChanges });
    }
}

我想我可以使用NewExpression( new {x.LaunchDate,x.ApplyLaunchDateChanges} )来传递属性集合,但我无法使其工作。

  • 您会使用相同的方法吗?

  • 如何拆分传递的Expression,以便获取NewExpression对象中找到的每个属性的propertyinfo?

1 个答案:

答案 0 :(得分:1)

好吧,因为ElementHelper.GetPropertyInfo是你自己的方法,你可以决定允许传递什么,然后在该方法中适当地处理它。

目前您只处理MemberExpression,这就是为什么它只适用于单个属性访问器。如果您希望能够通过new { ... },则需要添加对此NewExpression的支持:

private static IEnumerable<PropertyInfo> GetPropertyInfo<T1>(Expression<Func<TModel, T1>> propertyExpression)
{
    var memberExpression = propertyExpression.Body as MemberExpression;
    if (memberExpression != null)
        return Enumerable.Repeat((PropertyInfo)memberExpression.Member, 1);
    var newExpression = propertyExpression.Body as NewExpression;
    if (newExpression != null)
        return newExpression.Arguments.Select(item => (PropertyInfo)((MemberExpression)item).Member);
    return Enumerable.Empty<PropertyInfo>(); // or throw exception
}