Получить имя свойства, используемое в выражении Lambda в .NET 3.5

17

У меня есть проблема, которая время от времени натыкалась на меня, и я не могу найти ответ.

Мне нужно получить имя свойства, на которое ссылается выражение Lambda. Я бы предоставил лямбда-выражение методу, который возвращал бы строку. Например, если у меня есть:

x => x.WeirdPropertyName

, то метод вернется:

"WeirdPropertyName"

Я прочитал, что это можно сделать с помощью деревьев выражений, но ответ ускользнул от меня.

Спасибо за любую помощь

    
задан Carlos G. 17.07.2010 в 01:37
источник
  • Вы запрашиваете значение в свойстве или самом имени свойства? –  Chuck Conway 17.07.2010 в 01:56
  • Имя самого свойства –  Carlos G. 17.07.2010 в 02:03
  • @Yuriy Я не вижу, как эта статья касается моего вопроса –  Carlos G. 17.07.2010 в 02:05
  • @Kiranu Я согласен, но мой ответ делает именно то, что вы просили. Но мне все же нужно понять это лучше. –  Yuriy Faktorovich 17.07.2010 в 02:06
  • Возможный дубликат Как я могу получить имя поля из выражения? –  Thomas Levesque 17.07.2010 в 03:52

3 ответа

27

Здесь вы идете:

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;
}
    
ответ дан kiwipom 17.07.2010 в 02:07
источник
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
    );
}
    
ответ дан Dan Tao 17.07.2010 в 02:22
источник
-4

Единственный способ узнать имя строки свойства - через отражение.

    
ответ дан Chuck Conway 17.07.2010 в 01:47
источник