Получение имени свойства в С#
Учитывая этот класс:
public class MyClass
{
public int MyProperty {get; set;}
}
Как я смогу извлечь имя MyProperty
в коде?
Например, я могу получить название класса, как это
typeof(MyClass).Name
Как я могу сделать что-то подобное для собственности?
Причина этого вопроса в том, что я хочу, чтобы этот конкретный код был устойчивым к рефакторизации имен.
РЕДАКТИРОВАТЬ: С устойчивым я имею в виду, что я хочу, чтобы код на сайте вызовов был устойчивым перед лицом изменений имени свойства. У меня есть некоторые вещи, которые используют строковое представление имени свойства. Извините за плохую формулировку. Я не включил код сайта вызова, чтобы сохранить проблему в чистоте и не отвлекаться на другие дискуссии о природе кода сайта вызова.
Ответы
Ответ 1
Вы делаете это так, используя сгенерированные деревья выражений выражений:
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`
Теперь вы можете использовать рефакторинг, чтобы переименовать это поле, не нарушая этот код.
Ответ 2
В С# 6 мы можем сделать это очень просто
nameof(MyField);
вы можете получить имя метода \type\propery\field\class\namespace таким же образом
ех
nameof(MyClass);
nameof(namespacename1) // returns "namespacename1"
nameof(TestEnum.FirstValue) // returns enum first value
Ссылка MSDN
Посмотрите на это сообщение
Ответ 3
С С# 6.0 вы можете использовать новый оператор nameof
.
nameof(MyClass.MyField) // returns "MyField"
nameof(MyClass) //returns "MyClass"
Подробнее см. nameof (С# и ссылка на Visual Basic).
Ответ 4
Используя 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
Вы можете использовать следующий класс, который содержит метод с использованием дерева выражений в качестве аргумента для определения имени участника на основе выражения лямбда:
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);
Ответ 6
Если вы хотите получить имя члена экземпляра, вы можете использовать более короткий код:
public static string GetMemberName<TValue>(Expression<Func<TValue>> memberAccess)
{
return ((MemberExpression)memberAccess.Body).Member.Name;
}
И используйте его как внутри класса:
ReflectionTools.GetMemberName(() => _someInstanceVariableOrProperty)
Ответ 7
Если вы не хотите тратить свое время, попробуйте следующее. Я знаю, что люди столкнутся с той же проблемой.
// 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;
,