Можно ли получить строку имени свойства объекта без создания экземпляра объекта? - PullRequest
16 голосов
/ 15 ноября 2011

A строковое представление свойства экземпляра объекта может быть взято с Expression<Func<T>>:

string propertyName = ((MemberExpression) property.Body).Member.Name;

Но что, если у меня его нет (не хочу создавать)экземпляр?Как получить имя свойства в этом случае?

Объяснено

Мне нужно строковое представление имени свойства некоторого объекта.

Давайтескажем, есть сущность

public class Customer
{
    public int ID;
    public string Name;
}

Теперь я хочу передать ключевое выражение этой сущности какой-то другой функции, поэтому мне нужна строка «ID», но я не хочу жестко кодировать строку, напримерSomeOtherFunction("ID"), вместо этого я использую выражение SomeOtherFunction(ExpressionReader.GetString(() => CustomerInstance.ID)).Чтобы это работало, мне нужно предоставить экземпляр сущности.

Теперь я хочу сделать то же самое без создания экземпляра.

Ответы [ 5 ]

15 голосов
/ 15 ноября 2011

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

private static string GetPropertyName<TModel, TProperty>(Expression<Func<TModel, TProperty>> property)
{
    MemberExpression memberExpression = (MemberExpression)property.Body;

    return memberExpression.Member.Name;
}

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

string propertyName = GetPropertyName((Customer c) => c.ID);

Конечно, вам нужно добавить несколько проверок для правильных типов выражений, прежде чем вы приведете к MemberExpression и получите доступ к memberExpression.Member.Name.

4 голосов
/ 15 ноября 2011

Нет, вам не нужен экземпляр для декомпозиции Expression. Даже если выражение ожидает, вы никогда не будете вызывать его.

На самом деле, вы делаете это так же, как в первом фрагменте кода.

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

SomeOtherFunction(ExpressionReader<Customer>.GetString(c => c.ID))

Это имеет для вас смысл?

В качестве альтернативы:

Customer c = null; // null intentionally

SomeOtherFunction(ExpressionReader.GetString(() => c.ID));

Все еще нет проблем, поскольку вы не вызываете выражение.

2 голосов
/ 23 мая 2017

С новым nameof оператором C # 6 я бы предложил следующее:

 private string GetNameMyProperty1(TestC c = null)
 {
     return nameof(c.MyProperty1);
 }
0 голосов
/ 16 декабря 2013

Выбранный ответ хорош, но не распространяется на UnaryExpressions.Ошибка при попытке получить свойство DateTime:

    private static string GetPropertyName<TModel, TProperty>(Expression<Func<TModel, TProperty>> property)
    {
        if (property.Body is MemberExpression)
        {
            return ((MemberExpression)property.Body).Member.Name;
        }
        else
        {
            var op = ((UnaryExpression)property.Body).Operand;
            return ((MemberExpression)op).Member.Name;
        }  
    }
0 голосов
/ 15 ноября 2011

Я не уверен, что полностью понимаю, что вы имеете в виду, но исходя из моего понимания, вы можете использовать Reflection.Используя этот подход, если у вас было Type того, от чего вы хотели получить имя свойства, то вы можете получить свойства, используя:

Type someType = typeof(SomeClass);

// Get all properties for a type
PropertyInfo[] properties = someType.GetProperties();

// Get a property from a type by it's name
PropertyInfo property = someType.GetProperty("PropertyName");

Как только у вас есть экземпляр (ы) PropertyInfo class, вы можете получить информацию, такую ​​как имя свойства.

Подробнее об этом подходе см. в документации MSDN .

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