Поиск имени определенного свойства класса внутри класса в C# 3.5

Дайте класс, как показано ниже, как я могу найти имя одного конкретного свойства?

public class Student
{
    public int Grade
    {
        get;
        set;
    }

    public string TheNameOfTheGradeProperty
    {
        get
        {
            return ????
        }
    }

    // More properties..    
}

Поэтому я хотел бы вернуть строку «Оценка» из свойства TheNameOfTheGradeProperty. Причина, по которой я спрашиваю, заключается в том, что я не хочу использовать жестко закодированную строку, а скорее лямбда-выражение или что-то еще.

Как я могу этого добиться?


person andrej351    schedule 16.02.2010    source источник
comment
Если вы каким-то образом не ссылаетесь на свойство, имя которого хотите вернуть, это невозможно, и если вы это делаете, вы можете просто использовать жестко закодированную строку. Вы можете использовать отражение, но на данный момент мне это кажется бессмысленным. Каково ваше требование?   -  person johnc    schedule 16.02.2010
comment
@johnc иногда, когда при привязке данных вам нужно имя свойства, не все инструменты рефакторинга учитывают строковые литералы при переименовании свойств.   -  person Rohan West    schedule 16.02.2010
comment
@johnc ... за исключением приведенных ниже ответов, которые показывают, как выполнить запрос без использования жестко закодированной строки.   -  person John K    schedule 16.02.2010


Ответы (3)


Можно использовать выражение, чтобы найти имя свойства, используя простой метод расширения, вы можете использовать его для любого объекта... если вам нужно ограничить его набором объектов, вы можете применить общее ограничение к T. Надеюсь это поможет

public class Student
{
    public int Grade { get; set;}
    public string Name { get; set; }

    public string GradePropertyName
    {
        get { return this.PropertyName(s => s.Grade); }
    }

    public string NamePropertyName
    {
        get { return this.PropertyName(s => s.Name); }
    }
}

public static class Helper
{
    public static string PropertyName<T, TProperty>(this T instance, Expression<Func<T, TProperty>> expression)
    {
        var property = expression.Body as MemberExpression;

        if (property != null)
        {
            var info = property.Member as PropertyInfo;
            if (info != null)
            {
                return info.Name;
            }
        }

        throw new ArgumentException("Expression is not a property");
    }
}
person Rohan West    schedule 16.02.2010

У вас очень странная просьба. Вы говорите, что не хотите использовать жестко закодированную строку, потому что хотите, чтобы TheNameOfTheGradeProperty оставался в актуальном состоянии, если вы реорганизуете класс? Если да, то вот странный способ сделать это:

public class Student
{
    public int Grade { get; set; }

    public string TheNameOfTheGradeProperty
    {
        get
        {
            Expression<Func<int>> gradeExpr = () => this.Grade;
            MemberExpression body = gradeExpr.Body as MemberExpression;
            return body.Member.Name;
        }
    }
}
person Jacob    schedule 16.02.2010

using System.Reflection;

return typeof(Student).GetProperty("Grade").Name;

Но, как вы можете видеть, вы не так далеко продвинулись, используя отражение (таким образом), потому что строка «Оценка» по-прежнему жестко закодирована, что означает, что в этом сценарии более эффективно просто return "Grade".


Одна вещь, которую я люблю делать, — это создавать и добавлять настраиваемый атрибут для члена, например. Следующее избавляет вас от необходимости использовать жестко заданную строку "Оценка".

public class Student {

// TAG MEMBER WITH CUSTOM ATTRIBUTE
[GradeAttribute()]
public int Grade
{
    get;
    set;
}

public string TheNameOfTheGradeProperty
{
    get
    {
        /* Use Reflection.
           Loop over properties of this class and return the
           name of the one that is tagged with the 
           custom attribute of type GradeAttribute.
        */
    }
}

// More properties..    

} 

Создание настраиваемых атрибутов можно найти здесь.

person John K    schedule 16.02.2010
comment
Я не могу перестать улыбаться этому ответу. - person johnc; 16.02.2010
comment
@johnc: Это старомодно, бледнеет, учитывая функции 3.x, и, вероятно, является неправильным использованием атрибута, но, тем не менее, это вариант. Хотя и не самый гордый момент :) - person John K; 16.02.2010
comment
В коде нет ничего плохого, меня просто позабавила замечательная запутанность простого return Grade;. Я уверен, что у него есть потребность, я просто не знаю, что это такое на данный момент - person johnc; 16.02.2010