为了账号安全,请及时绑定邮箱和手机立即绑定

在C#中组合两个Lambda表达式

在C#中组合两个Lambda表达式

C#
忽然笑 2019-12-25 14:12:44
给定这样的类结构:public class GrandParent{    public Parent Parent { get; set;}}public class Parent{    public Child Child { get; set;}}public class Child{    public string Name { get; set;}}和以下方法签名:Expression<Func<TOuter, TInner>> Combine (Expression<Func<TOuter, TMiddle>>> first, Expression<Func<TMiddle, TInner>> second);我如何实现上述方法,以便可以这样调用它:Expression<Func<GrandParent, Parent>>> myFirst = gp => gp.Parent;Expression<Func<Parent, string>> mySecond = p => p.Child.Name;Expression<Func<GrandParent, string>> output = Combine(myFirst, mySecond);这样输出结果如下:gp => gp.Parent.Child.Name这可能吗?每个Func的内容只会是一个MemberAccess。我不想最终output成为嵌套函数调用。谢谢
查看完整描述

3 回答

?
温温酱

TA贡献1752条经验 获得超4个赞

我假设您的目标是获得您实际上已经编译了“组合” lambda 的表达式树。构造一个新的表达式树来简单地适当地调用给定的表达式树要容易得多,但是我认为这不是您想要的。

  • 首先提取主体,然后将其转换为MemberExpression。称这个为第一身体。

  • 提取秒的主体,称为thisBody

  • 首先提取参数。将此称为第一Param。

  • 提取秒的参数。将此称为第二Param。

  • 现在,困难的部分。编写访问者模式实现,该访问者搜索secondBody以查找secondParam的单个用法。(如果您知道这只是成员访问表达式,则可以轻松得多,但可以总体上解决该问题。)找到它后,构造一个与其父类型相同类型的新表达式,用firstBody代替该参数。在退出的路上继续重建经过转换的树;请记住,您只需重建包含参数引用的树的“书脊”即可。

  • 访客通行证的结果将是重写的secondBody,不出现secondParam,仅出现涉及firstParam的表达式。

  • 构造一个新的lambda表达式,以该主体作为主体,并以firstParam作为其参数。

  • 完成了!

Matt Warren的博客对您来说可能是一件好事。他设计并实现了所有这些东西,并写了很多有关有效重写表达式树的方法。(我只完成了编译器的工作。)

更新:

正如这个相关答案所指出的那样,.NET 4中现在有一个用于表达式重写器的基类,它使这种事情变得容易得多。


查看完整回答
反对 回复 2019-12-25
  • 3 回答
  • 0 关注
  • 642 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信