使用表达式数组中的索引获取 lambda 表达式的名称
Get the name of the lambda expression with the index from the expression's array
我需要获取查询别名的表达式名称。
我需要它:
Customer customer = null;
string expressionAdresses2Number = ExpressionUtils.PathString(() => customer.Adresses[2].Number);
而我想要的结果是"Adresses[2].Number",但我只能得到"Adresses.Number",我无法得到表达式的数组部分。
我试过这个例子:https://dotnetfiddle.net/eJ5nvl
(基于这个例子:)
有没有人对如何获取索引选择为“[2]”的数组的表达式部分有任何建议?
模型示例:
public class Customer
{
public int Id { get; set; }
public Adress Adress { get; set; }
public IList<Adress> Adresses { get; set; }
}
public class Adress
{
public int Id { get; set; }
public int Number { get; set; }
}
索引器被转换为 MethodCallExpression
,因此您需要覆盖 VisitMethodCall
。
你可以这样做访客:
public class PathVisitor : ExpressionVisitor
{
// You should not use MemberInfo for the list type anymore, since the path can have indexer expressions now!
// Here I convert both the indexer expressions and the member accesses to string in the visitor
// You can do something more fancy, by creating your own class that represents either of these two cases
// and then formatting them afterwards.
internal readonly List<string> Path = new List<string>();
protected override Expression VisitMember(MemberExpression node)
{
if (node.Member is PropertyInfo)
{
Path.Add(node.Member.Name);
}
return base.VisitMember(node);
}
protected override Expression VisitMethodCall(MethodCallExpression node) {
if (node.Method.Name == "get_Item") { // name of the indexer
// you can format this in a better way on your own. This is just an example
Path.Add(node.Arguments.First().ToString());
}
return base.VisitMethodCall(node);
}
}
用法:
public static IReadOnlyList<string> Get(LambdaExpression expression)
{
var visitor = new PathVisitor();
visitor.Visit(expression.Body);
visitor.Path.Reverse();
return visitor.Path;
}
public static string PathString(Expression<Func<object>> expression)
{
return string.Join(".", Get(expression));
}
这会为您的 lambda 生成 Adresses.2.Number
的输出。
请注意,这假设 lambda 仅具有 属性 访问和具有常量参数的索引器。
我需要获取查询别名的表达式名称。
我需要它:
Customer customer = null;
string expressionAdresses2Number = ExpressionUtils.PathString(() => customer.Adresses[2].Number);
而我想要的结果是"Adresses[2].Number",但我只能得到"Adresses.Number",我无法得到表达式的数组部分。
我试过这个例子:https://dotnetfiddle.net/eJ5nvl (基于这个例子:)
有没有人对如何获取索引选择为“[2]”的数组的表达式部分有任何建议?
模型示例:
public class Customer
{
public int Id { get; set; }
public Adress Adress { get; set; }
public IList<Adress> Adresses { get; set; }
}
public class Adress
{
public int Id { get; set; }
public int Number { get; set; }
}
索引器被转换为 MethodCallExpression
,因此您需要覆盖 VisitMethodCall
。
你可以这样做访客:
public class PathVisitor : ExpressionVisitor
{
// You should not use MemberInfo for the list type anymore, since the path can have indexer expressions now!
// Here I convert both the indexer expressions and the member accesses to string in the visitor
// You can do something more fancy, by creating your own class that represents either of these two cases
// and then formatting them afterwards.
internal readonly List<string> Path = new List<string>();
protected override Expression VisitMember(MemberExpression node)
{
if (node.Member is PropertyInfo)
{
Path.Add(node.Member.Name);
}
return base.VisitMember(node);
}
protected override Expression VisitMethodCall(MethodCallExpression node) {
if (node.Method.Name == "get_Item") { // name of the indexer
// you can format this in a better way on your own. This is just an example
Path.Add(node.Arguments.First().ToString());
}
return base.VisitMethodCall(node);
}
}
用法:
public static IReadOnlyList<string> Get(LambdaExpression expression)
{
var visitor = new PathVisitor();
visitor.Visit(expression.Body);
visitor.Path.Reverse();
return visitor.Path;
}
public static string PathString(Expression<Func<object>> expression)
{
return string.Join(".", Get(expression));
}
这会为您的 lambda 生成 Adresses.2.Number
的输出。
请注意,这假设 lambda 仅具有 属性 访问和具有常量参数的索引器。