How to get the name of the property to which a lambda expression refers?

Asked

Viewed 491 times

4

I have a lambda expression being translated into an expression tree (Expression Tree) as follows:

Expression<Func<object>> expr = () => x.NomeDaPropriedade;

How do I get the name of the property, which in this case is NomeDaPropriedade, from that expression tree?

4 answers

3

public string AnalizarPropriedade<T>(Expression<T> expr)
{
    var memberExpr = expr.Body as UnaryExpression; // parse da expressao "x.y"
    var operand = memberExpr.Operand as MemberExpression; // parse do operando "y"
    return operand.Member.Name; // parse do nome do operando "y"
}

Unitary test:

[Fact]
public void AnaliseDeExpressao_Retorna_NomeDaPropriedade()
{
    //com closure
    string str = "ola";
    Expression<Func<object>> expr = () => str.Length;
    Assert.Equal("Length", AnalizarPropriedade(expr));

    //sem closure
    Expression<Func<string, object>> expr2 = s => s.Length;
    Assert.Equal("Length", AnalizarPropriedade(expr2));
}

3


This function tries to recover the name by casting it as Memberexpression, if it doesn’t work it does by Unaryexpression.

public static string GetName(Expression<Func<object>> exp)
{
    MemberExpression body = exp.Body as MemberExpression;

    if (body == null) {
       UnaryExpression ubody = (UnaryExpression)exp.Body;
       body = ubody.Operand as MemberExpression;
    }

    return body.Member.Name;
}
  • That’s exactly what I wanted. Thanks!

2

You can take the property by the body of the lambda maybe the method below will solve...

public String ObterNome<T> (Expression<Func<T, object>> expressao)
{
        var lambda = (LambdaExpression) expressao;

        MemberExpression memberExpression;
        if (lambda.Body is UnaryExpression) {
            var unaryExpression = (UnaryExpression) lambda.Body;
            memberExpression = (MemberExpression) unaryExpression.Operand;
        }
        else {
            memberExpression = (MemberExpression) lambda.Body;
        }

        var member = memberExpression.Member;

        if( member == null ) return null;
        return member.Name;
}

the use is like this

string nomePropriedade = ObterNomePropriedade<Pessoa>( x => x.Endereco );
  • In my code he did more things, I tried to simplify, but

0

Well, just to summarize the answers already given, and based on them, I created two auxiliary methods to help in this task when necessary, depending on the lambda format used:

public String ObterNome<TIn>(Expression<Func<TIn, object>> expression)
{
    return ObterNome(expression as Expression);
}

public String ObterNome<TOut>(Expression<Func<TOut>> expression)
{
    return ObterNome(expression as Expression);
}

private String ObterNome(Expression expression)
{
    var lambda = expression as LambdaExpression;
    var member = lambda.Body.NodeType == ExpressionType.Convert
                        ? ((UnaryExpression)lambda.Body).Operand as MemberExpression
                        : lambda.Body as MemberExpression;
    return member.Member.Name;
}

There is a method to obtain the name, if a lambda with closure is used, which points to the property, and another to the case where there is no closure, but it is necessary to indicate the type of the generic parameter.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.