【发布时间】:2015-07-20 11:56:58
【问题描述】:
我正在编写一种映射工具。我有一个看起来像这样的方法(简化):
public void RegisterMapping<TTarget, TSource>(string propertyName,
Expression<Func<TSource, object>> memberMap)
memberMap 是一个表达式,用于定义如何将属性从 TSource 转换为 TTarget。对于业务逻辑,我需要从中提取对TSource 属性的所有引用。例如,来自
x => x.Customers.Where(c => c.Orders.Any())
我想得到Customers,并来自
x => x.FirstName + " " + x.LastName
FirstName 和 LastName(可以是 string[],PropertyInfo 很容易转换为)。
我该怎么做?我的第一种方法是手动遍历树,检查节点类型并根据节点类型检查不同的属性(例如,Operand 用于一元表达式,Arguments 用于函数调用)以确定其中任何一个是TSource。然后我发现了expression kind list 然后我放弃了——即使我只支持最常见的类型,它仍然需要做很多工作。然后我找到了ExpressionVisitor。它看起来更好,但是覆盖访问者方法仍然需要做很多工作,我想知道是否还有其他选择,使用可能更专业的框架,然后再花时间解决这个问题。
【问题讨论】:
-
看一下ASP.MVC团队的
ExpressionHelper代码:(github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/…)。
标签: c# linq reflection lambda traversal