改变Lambda表达式更深入一级

时间:2016-03-01 20:25:39

标签: c# lambda expression-trees

假设我有这样的方法:

public void MultiDropDown<T>(Expression<Func<T, DropDownModel<DropDownItem>>> expression)
{

   // Here i want to get more specific with the expression selector
   // Suppose it was passed like this: 
   //                                  MultiDropDown(x => x.MyDropDown);
   // I need to alter `expression` and go deeper:    x => x.MyDropDown.Title;
   // And then use the new expression for other stuff...
}

解决方案

感谢svick!

public void MultiDropDown<T>(Expression<Func<T, DropDownModel<DropDownItem>>> expression)
{
        // 1. Build a new expression and select the final property
        Expression<Func<DropDownModel<DefaultDropDownItem>, object>> childExpression = x => x.Title;
        // 2. Extract property name
        var propName = (childExpression.Body as MemberExpression).Member.Name;
        // 3. Create a MemberExpression selection from parent's Body
        var expressionProperty = Expression.Property(expression.Body, propName);
        // 4. Finally create a Lambda Expression
        var refinedExpression = Expression.Lambda<Func<TModel, object>>(expressionProperty, expression.Parameters);
}

操作1.和2.仅仅是为了避免使用“标题”字符串而是依赖于强类型模型。

1 个答案:

答案 0 :(得分:4)

您需要创建一个表达式,该表达式接受查询的Body并访问其上的给定属性。然后你需要构建lambda表达式。整件事看起来像这样:

var titleExpression = Expression.Lambda<Func<T, string>>(
    Expression.Property(expression.Body, "Title"), expression.Parameters);