Alter Lambda Expression to go one level deeper

爷,独闯天下 提交于 2019-12-24 20:33:14

问题


Suppose I have a method like this:

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...
}

Solution

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

Operations 1. and 2. were done just for avoiding "Title" string and relying on Strongly Typed model instead.


回答1:


What you need is to create an expression that takes the Body of your query and accesses the given property on it. Then you need to build back the lambda expression. The whole thing looks like this:

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


来源:https://stackoverflow.com/questions/35732763/alter-lambda-expression-to-go-one-level-deeper

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!