代码之家  ›  专栏  ›  技术社区  ›  Carlos G.

获取.NET 3.5中lambda表达式中使用的属性名

  •  17
  • Carlos G.  · 技术社区  · 15 年前

    我有一个问题一直在困扰我一段时间,我找不到答案。

    我需要获取lambda表达式中引用的属性的名称。我将为将返回字符串的方法提供lambda表达式。例如,如果我有:

    x => x.WeirdPropertyName
    

    然后该方法将返回:

    "WeirdPropertyName"
    

    我读过,它可以用表达树来完成,但我却没有得到答案。

    谢谢你的帮助

    3 回复  |  直到 15 年前
        1
  •  28
  •   kiwipom    15 年前

    干得好:

    string GetPropertyName<T>(Expression<Func<T>> property)
    {
        var propertyInfo = (property.Body as MemberExpression).Member as PropertyInfo;
        if (propertyInfo == null)
        {
            throw new ArgumentException("The lambda expression 'property' should point to a valid Property");
        }
        return propertyInfo.Name;
    }
    
        2
  •  6
  •   Community Mohan Dere    8 年前

    我有一个相当全面的答案 here .

    除了处理像 x => x.WeirdPropertyName 它还可以处理“扩展”表达式,例如 x => x.WeirdMember.WeirdPropertyName .

    这是那个答案的代码:

    // code adjusted to prevent horizontal overflow
    static string GetFullPropertyName<T, TProperty>
    (Expression<Func<T, TProperty>> exp)
    {
        MemberExpression memberExp;
        if (!TryFindMemberExpression(exp.Body, out memberExp))
            return string.Empty;
    
        var memberNames = new Stack<string>();
        do
        {
            memberNames.Push(memberExp.Member.Name);
        }
        while (TryFindMemberExpression(memberExp.Expression, out memberExp));
    
        return string.Join(".", memberNames.ToArray());
    }
    
    // code adjusted to prevent horizontal overflow
    private static bool TryFindMemberExpression
    (Expression exp, out MemberExpression memberExp)
    {
        memberExp = exp as MemberExpression;
        if (memberExp != null)
        {
            // heyo! that was easy enough
            return true;
        }
    
        // if the compiler created an automatic conversion,
        // it'll look something like...
        // obj => Convert(obj.Property) [e.g., int -> object]
        // OR:
        // obj => ConvertChecked(obj.Property) [e.g., int -> long]
        // ...which are the cases checked in IsConversion
        if (IsConversion(exp) && exp is UnaryExpression)
        {
            memberExp = ((UnaryExpression)exp).Operand as MemberExpression;
            if (memberExp != null)
            {
                return true;
            }
        }
    
        return false;
    }
    
    private static bool IsConversion(Expression exp)
    {
        return (
            exp.NodeType == ExpressionType.Convert ||
            exp.NodeType == ExpressionType.ConvertChecked
        );
    }
    
        3
  •  -4
  •   Chuck Conway    15 年前

    我知道获取属性字符串名称的唯一方法是通过反射。