在.NET 3.5中,获取Lambda表达式中使用的属性名称

17

我有一个问题困扰了我一段时间,但是我找不到答案。

我需要获取Lambda表达式中所引用的属性名称。我会将Lambda表达式提供给一个方法,然后该方法会返回一个字符串。例如,如果我有以下代码:

x => x.WeirdPropertyName

那么该方法将返回:

"WeirdPropertyName"

我已经阅读了可以使用表达式树来完成,但是这个答案让我难以理解。

感谢任何帮助。


你是在询问属性的值还是属性名称本身? - Chuck Conway
属性名称本身 - Carlos G.
@Yuriy 我不明白那篇文章与我的问题有什么关系。 - Carlos G.
@Kiranu 我同意,但我的回答正好符合你的要求。但我仍然需要更好地理解它。 - Yuriy Faktorovich
1
可能是重复的问题:如何从表达式中获取字段名称? - Thomas Levesque
@Thomas 是的,有点这个意思。 - Carlos G.
3个回答

28

请看这里:

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;
}

6
我在这里得到了一个相当全面的答案(链接)与处理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
    );
}

-4
我所知道的获取属性名称的唯一方法是通过反射。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接