如何将嵌套表达式列表拆分为单层表达式列表?

时间:2015-09-07 05:06:05

标签: c# lambda

假设我有List<Expression<Func<SomeModel, object>>>,如下所示:

x => x.Property1,
x => x.Property1.P1ChildProperty1,
x => x.Property1.P1ChildProperty2,
x => x.Property2,
x => x.Property2.P2ChildProperty1,
x => x.Property2.P2ChildProperty2,
x => x.Property2.P2ChildProperty3

我是否可以通过某种方式迭代该列表,并生成一组新的列表,这些列表只有一级深度,如下所示:

清单1:

x => x.Property1,
x => x.Property2

清单2:

y => y.P1ChildProperty1,
y => y.P1ChildProperty2

清单3:

z => z.P2ChildProperty1,
z => z.P2ChildProperty2,
z => z.P2ChildProperty3

1 个答案:

答案 0 :(得分:1)

是的,有办法做到这一点。但这取决于你的班级结构。

var items = new List<Expression<Func<SomeModel, object>>>
            {
                x => x.Property1,
                x => x.Property1.P1ChildProperty1,
                x => x.Property1.P1ChildProperty2,
                x => x.Property2,
                x => x.Property2.P2ChildProperty1,
                x => x.Property2.P2ChildProperty2,
                x => x.Property2.P2ChildProperty3
            };
Func<LambdaExpression, Expression<Func<object, object>>> reBase = 
            x =>
            {
                var memExpr = (MemberExpression)x.Body;
                var param = Expression.Parameter(typeof(object), "x");
                var typedParam = Expression.Convert(param, memExpr.Member.DeclaringType);
                var property = Expression.Property(typedParam, memExpr.Member.Name);
                return Expression.Lambda<Func<object, object>>(property, param);
            };

var groupedItems = (from item in items
                    group item by ((MemberExpression)item.Body).Member.DeclaringType into g
                    select g.Select(x => reBase(x)).ToList()).ToList();

之后groupedItems包含您想要的基于重新分割的分割列表。

问题是它要求声明类型。这仅在您声明具有此属性的类型时才有效:

  • SomeModelProperty1类型Child1Property2类型Child2
  • <Child1>P1ChildProperty1P1ChildProperty2
  • <Child2>P1ChildProperty1P1ChildProperty2P1ChildProperty3

我不确定这对你有什么帮助。也许你应该深入研究表达式树,找到一种更好的方法来分割你的列表。

请注意,这会将lambda签名从Func<SomeModel, object>更改为Func<object, object>