Search code examples
c#linqlambdaexpression-trees

Retrieving Property name from lambda expression


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<User>(u => u.UserId);

It worked by casting it as a memberexpression only when the property was a string. because not all properties are strings i had to use object but then it would return a unaryexpression for those.

public static RouteValueDictionary GetInfo<T>(this HtmlHelper html, 
    Expression<Func<T, object>> action) where T : class
{
    var expression = GetMemberInfo(action);
    string name = expression.Member.Name;

    return GetInfo(html, name);
}

private static MemberExpression GetMemberInfo(Expression method)
{
    LambdaExpression lambda = method as LambdaExpression;
    if (lambda == null)
        throw new ArgumentNullException("method");

    MemberExpression memberExpr = null;

    if (lambda.Body.NodeType == ExpressionType.Convert)
    {
        memberExpr = 
            ((UnaryExpression)lambda.Body).Operand as MemberExpression;
    }
    else if (lambda.Body.NodeType == ExpressionType.MemberAccess)
    {
        memberExpr = lambda.Body as MemberExpression;
    }

    if (memberExpr == null)
        throw new ArgumentException("method");

    return memberExpr;
}

Solution

  • I found another way you can do it was to have the source and property strongly typed and explicitly infer the input for the lambda. Not sure if that is correct terminology but here is the result.

    public static RouteValueDictionary GetInfo<T,P>(this HtmlHelper html, Expression<Func<T, P>> action) where T : class
    {
        var expression = (MemberExpression)action.Body;
        string name = expression.Member.Name;
    
        return GetInfo(html, name);
    }
    

    And then call it like so.

    GetInfo((User u) => u.UserId);
    

    and voila it works.