鉴于
Expression<Func<T, object>>
Run Code Online (Sandbox Code Playgroud)
(例如x => x.Prop1.SubProp),我想根据需要创建一个字符串"Prop1.SubProp".
在单次访问的情况下(例如x => x.Prop1),我可以轻松地执行以下操作:
MemberExpression body = (expression.Body.NodeType == ExpressionType.Convert) ? (MemberExpression)((UnaryExpression)expression.Body).Operand : (MemberExpression)expression.Body;
return body.Member.Name;
Run Code Online (Sandbox Code Playgroud)
但是,如果存在更深的嵌套,例如x => x.Prop1.SubProp1,则只获得嵌套最深的名称,例如"SubProp1"而不是"Prop1.SubProp1"
反正有没有访问lambda表达式的完整属性路径?
Luk*_*keH 34
public string GetPath<T>(Expression<Func<T, object>> expr)
{
var stack = new Stack<string>();
MemberExpression me;
switch (expr.Body.NodeType)
{
case ExpressionType.Convert:
case ExpressionType.ConvertChecked:
var ue = expr.Body as UnaryExpression;
me = ((ue != null) ? ue.Operand : null) as MemberExpression;
break;
default:
me = expr.Body as MemberExpression;
break;
}
while (me != null)
{
stack.Push(me.Member.Name);
me = me.Expression as MemberExpression;
}
return string.Join(".", stack.ToArray());
}
Run Code Online (Sandbox Code Playgroud)
看看我对这个问题的回答.
与LukeH发布的内容几乎相同,还有一个附加功能:
如果你有一个类型,比如说MyClass,有物业MyProperty类型的int,你可以这样写:
Expression<Func<MyClass, object>> e = x => x.MyProperty;
Run Code Online (Sandbox Code Playgroud)
这里表达的e.Body是不是一个MemberExpression这么简单的while (me != null) me = me.Expression as MemberExpression将无法工作.
解决方案是另外检查它是否UnaryExpression与NodeType == Convert或ConvertChecked.
可能还有其他方案需要考虑; 但对于简单的属性表达式链,这种方法非常有效.