给定以下类
public class Person
{
public string Name { get; }
public List<Person> Friends { get; }
}
我正在寻找一种方法来获得以下字符串"朋友。名称",当使用表达式>时。
下面是我想要做的伪代码:
Expression<Func<Person,string>> exp = x => x.Friends.Name
由于显而易见的原因无法编译。
我怎么才能做到呢?即使你没有代码,一个通用的方法也可以做到这一点,因为我在这方面缺乏灵感。
谢谢
你不能得到你想要的,使用这种类型的表达式:
Expression<Func<Person,string>>
,因为Person
有Friends
的集合。实际上,Func
的返回类型在这里并不重要。
static string GetPath(Expression<Func<Person, object>> expr)
{
var selectMethodCall = (MethodCallExpression)expr.Body;
var collectionProperty = (MemberExpression)selectMethodCall.Arguments[0];
var collectionItemSelector = (LambdaExpression)selectMethodCall.Arguments[1];
var collectionItemProperty = (MemberExpression)collectionItemSelector.Body;
return $"{collectionProperty.Member.Name}.{collectionItemProperty.Member.Name}";
}
用法:
var path = GetPath(_ => _.Friends.Select(f => f.Name)); // Friends.Name
但这是一个相当简单的情况下,而在我看来,你正在做的事情像Include
方法从实体框架。
所以,如果你想解析更复杂的表达式,像这样:
_ => _.Friends.Select(f => f.Children.Select(c => c.Age))
您需要以更通用的方式来探索表达式
假设如下所示,您可以获得如下路径:
Expression<Func<Person, string>> exp = x => x.Name;
var lambdaBody = exp.Body;
if(lambdaBody.NodeType == ExpressionType.MemberAccess)
{
var memberExpression = lambdaBody as MemberExpression;
Console.WriteLine(memberExpression.ToString());
}
输出:x.Name