【发布时间】:2021-05-26 10:21:02
【问题描述】:
我正在尝试编写一个扩展方法来从给定的LambdaExpression 检索属性路径。
我希望能够这样称呼它
var path = ((Event e) => e.Address.City.Name).ToChainedPath();
这将返回 Address.City.Name 作为 string 由 . 分隔。
目前我的扩展是这样的
public static string ToChainedPath<TSource, TProperty>(this Expression<Func<TSource, TProperty>> expr, char separator = '.')
{
MemberExpression me;
switch (expr.Body.NodeType)
{
case ExpressionType.Convert:
case ExpressionType.ConvertChecked:
var ue = expr.Body as UnaryExpression;
me = ue?.Operand as MemberExpression;
break;
default:
me = expr.Body as MemberExpression;
break;
}
var propertyNames = new List<string>();
while (me != null)
{
propertyNames.Add(me.Member.Name);
me = me.Expression as MemberExpression;
}
propertyNames.Reverse();
return string.Join(separator, propertyNames);
}
像这样使用时效果很好
Expression<Func<Event, string>> expression = e => e.Address.City.Name;
var propertyChain = expression.ToChainedPath();
但这不适用于我想要的,因为(Event e) => e.Address.City.Name 是Func<Event, string> 而不是Expression<Func<Event,string>>。
我已经尝试将Func 转换为Expression,但到目前为止没有任何帮助。
我还将扩展名更改为扩展Func 而不是Expression,但后来我失去了Body。
这有可能吗?
【问题讨论】:
-
您的确切要求是不可能的。一些类似的语法是可能的:
((Expression<Func<Event, string>>)(e => e.Address.City.Name)).ToChainedPath()或GetChainedPath(e => e.Address.City.Name)。 -
@Sweeper 我担心这是不可能的。因此,我将采用第二种方法并将扩展名留在后面。感谢您的澄清。如果您发布答案,我可以将其标记为解决方案
标签: c# function lambda expression