繁体   English   中英

使用表达式数组中的索引获取 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://do.netfiddle.net/eJ5nvl (基于这个例子: https://stackoverflow.com/a/22135756/2290538

有没有人对如何获取索引选择为“[2]”的数组的表达式部分有任何建议?

Model 示例:

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 的Adresses.2.Number

请注意,这假定 lambda 仅具有常量 arguments 的属性访问和索引器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM