Retrieving Property name from lambda expression

前端 未结 21 1681
迷失自我
迷失自我 2020-11-21 11:12

Is there a better way to get the Property name when passed in via a lambda expression? Here is what i currently have.

eg.

GetSortingInfo         


        
21条回答
  •  隐瞒了意图╮
    2020-11-21 11:43

    There's an edge case when it comes to Array.Length. While 'Length' is exposed as a property, you can't use it in any of the previously proposed solutions.

    using Contract = System.Diagnostics.Contracts.Contract;
    using Exprs = System.Linq.Expressions;
    
    static string PropertyNameFromMemberExpr(Exprs.MemberExpression expr)
    {
        return expr.Member.Name;
    }
    
    static string PropertyNameFromUnaryExpr(Exprs.UnaryExpression expr)
    {
        if (expr.NodeType == Exprs.ExpressionType.ArrayLength)
            return "Length";
    
        var mem_expr = expr.Operand as Exprs.MemberExpression;
    
        return PropertyNameFromMemberExpr(mem_expr);
    }
    
    static string PropertyNameFromLambdaExpr(Exprs.LambdaExpression expr)
    {
             if (expr.Body is Exprs.MemberExpression)   return PropertyNameFromMemberExpr(expr.Body as Exprs.MemberExpression);
        else if (expr.Body is Exprs.UnaryExpression)    return PropertyNameFromUnaryExpr(expr.Body as Exprs.UnaryExpression);
    
        throw new NotSupportedException();
    }
    
    public static string PropertyNameFromExpr(Exprs.Expression> expr)
    {
        Contract.Requires(expr != null);
        Contract.Requires(expr.Body is Exprs.MemberExpression || expr.Body is Exprs.UnaryExpression);
    
        return PropertyNameFromLambdaExpr(expr);
    }
    
    public static string PropertyNameFromExpr(Exprs.Expression> expr)
    {
        Contract.Requires(expr != null);
        Contract.Requires(expr.Body is Exprs.MemberExpression || expr.Body is Exprs.UnaryExpression);
    
        return PropertyNameFromLambdaExpr(expr);
    }
    

    Now example usage:

    int[] someArray = new int[1];
    Console.WriteLine(PropertyNameFromExpr( () => someArray.Length ));
    

    If PropertyNameFromUnaryExpr didn't check for ArrayLength, "someArray" would be printed to the console (compiler seems to generate direct access to the backing Length field, as an optimization, even in Debug, thus the special case).

提交回复
热议问题