Получение имени свойства в c # - PullRequest
28 голосов
/ 29 сентября 2011

Учитывая этот класс:

public class MyClass
{
    public int MyProperty {get; set;}
}

Как я смогу извлечь имя MyProperty в коде?

Например, я могу получить название класса следующим образом

typeof(MyClass).Name

Как я могу сделать что-то подобное для собственности?

Причина вопроса в том, что я хочу, чтобы этот конкретный код был устойчивым к рефакторизации имен.

РЕДАКТИРОВАТЬ: Имея в виду устойчивый, я имею в виду, что я хочу, чтобы код на сайте вызовов был надежным перед лицом изменений имени свойства. У меня есть некоторые вещи, которые используют строковое представление имени свойства. Извините за плохую формулировку. Я не включил код сайта вызова, чтобы сохранить проблему в чистоте и не отвлекаться на другие дискуссии о природе кода сайта вызова.

Ответы [ 7 ]

47 голосов
/ 29 сентября 2011

Вы делаете это так, используя сгенерированные компилятором деревья выражений:

public static string GetMemberName<T, TValue>(Expression<Func<T, TValue>> memberAccess)
{
    return ((MemberExpression)memberAccess.Body).Member.Name;
}

Теперь вызовите статический метод из кода:

class MyClass
{
    public int Field;
    public string Property { get; set; }
}

var fieldName = GetMemberName((MyClass c) => c.Field);
var propertyName = GetMemberName((MyClass c) => c.Property);
// fieldName has string value of `Field`
// propertyName has string value of `Property`

Теперь вы также можете использовать рефакторинг, чтобы переименовать это поле, не нарушая этот код

28 голосов
/ 11 октября 2015

В C # 6 мы можем сделать это очень просто

nameof(MyField);

вы можете получить имена методов \ type \ Propery \ field \ class \ namespace таким же образом ех

 nameof(MyClass);
 nameof(namespacename1)  // returns "namespacename1"
 nameof(TestEnum.FirstValue) // returns enum's first value

Ссылка MSDN

Посмотрите на этот пост

10 голосов
/ 26 августа 2015

С C # 6.0 вы можете использовать новый оператор nameof.

nameof(MyClass.MyField)  // returns "MyField"
nameof(MyClass)  //returns "MyClass"

См. nameof (C # и Visual Basic Reference) для дополнительных примеров.

8 голосов
/ 25 августа 2015

Используя Reflection, вы можете найти всех участников из MyClass с этим.

    MemberInfo[] members = typeof(MyClass).GetMembers();

Теперь вы можете найти желаемое свойство для каждого участника.

    foreach ( MemberInfo memberInfo in members)
    {
        Console.WriteLine("Name: {0}", memberInfo.Name); // Name: MyField
        Console.WriteLine("Member Type: {0}", memberInfo.MemberType); // Member Type: Property
    }

Если вы хотитенаходить только свойства используют PropertyInfo вместо MemberInfo.Или напишите это

    foreach ( MemberInfo memberInfo in members.Where(p => p.MemberType == MemberTypes.Property))
    {
        Console.WriteLine("Name: {0}", memberInfo.Name); // Name: MyField
        Console.WriteLine("Member Type: {0}", memberInfo.MemberType); // Member Type: Property
    }
5 голосов
/ 29 сентября 2011

Вы можете использовать следующий класс, который содержит метод, использующий дерево выражений в качестве аргумента для определения имени члена на основе лямбда-выражения:

public class MemberHelper<T>
{
    public string GetName<U>(Expression<Func<T, U>> expression)
    {
        MemberExpression memberExpression = expression.Body as MemberExpression;
        if (memberExpression != null)
            return memberExpression.Member.Name;

        throw new InvalidOperationException("Member expression expected");
    }
}

Тогда используйте это так:

MemberHelper<MyClass> memberHelper = new MemberHelper<MyClass>();
string name = memberHelper.GetName(x => x.MyField);
3 голосов
/ 14 августа 2014

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

    public static string GetMemberName<TValue>(Expression<Func<TValue>> memberAccess)
    {
        return ((MemberExpression)memberAccess.Body).Member.Name;
    }

И используйте его следующим образом в классе:

    ReflectionTools.GetMemberName(() => _someInstanceVariableOrProperty)
0 голосов
/ 11 июля 2019

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

// Soner - tested!
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(item))
{
    string name = descriptor.Name;              // Name
    object value = descriptor.GetValue(item);   // Value
    var type = descriptor.PropertyType;         // Type
    Console.WriteLine($"{name}={value}={type}");
}

Не забудьте добавить using System.ComponentModel;.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...