Получить строковое имя свойства с помощью отражения

Существует множество примеров отражения, которые позволят вам получить либо:

    1. Все свойства в классе

    2. Одно свойство, если вы знаете название строки.

Есть ли способ (с использованием отражения, TypeDescriptor или иначе) получить строковое имя свойства в классе во время выполнения, при условии, что все, что у меня есть, - это экземпляр класса и свойства?

ИЗМЕНИТЬ. Я знаю, что могу легко получить все свойства класса с помощью отражения, а затем получить имя каждого свойства. Я прошу функцию, чтобы дать мне имя свойства, при условии, что я передам ему экземпляр свойства. Другими словами, как мне найти свойство, которое я хочу, в массиве PropertyInfo [], возвращенном мне из class.GetType (). GetProperty (myProperty), чтобы я мог получить от него PropertyInfo.Name?


person Joel B    schedule 07.09.2010    source источник
comment
Вы имеете в виду получить имя свойства в получателе / ​​установщике свойства? Что вы имеете в виду, что у вас есть недвижимость?   -  person Jacob    schedule 07.09.2010
comment
@Jacob - Чтобы добавить ясности, у меня есть экземпляр класса со свойством (а также другими свойствами), для которого я хочу получить строковое имя (не получатель / установщик). Мне нужно поработать над этим свойством с помощью Reflection, но я не хочу поддерживать код с жестко заданными строковыми именами на случай, если я реорганизую имя свойства. Таким образом, я хочу программно получить имя свойства.   -  person Joel B    schedule 07.09.2010
comment
Как еще можно определить желаемую недвижимость, как не по названию?   -  person We Are All Monica    schedule 07.09.2010
comment
См. Мое обновление, чтобы узнать, как получить имя свойства из выражения свойства expression.   -  person Jacob    schedule 07.09.2010
comment
возможный дубликат Получить имя и тип свойства с помощью лямбда-выражения   -  person nawfal    schedule 27.04.2013


Ответы (7)


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

var stackTrace = new StackTrace();
var frames = stackTrace.GetFrames();
var thisFrame = frames[0];
var method = thisFrame.GetMethod();
var methodName = method.Name; // Should be get_* or set_*
var propertyName = method.Name.Substring(4);

Изменить:

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

public static string GetPropertyName<T>(Expression<Func<T>> propertyExpression)
{
    return (propertyExpression.Body as MemberExpression).Member.Name;
}

Чтобы использовать это, вы должны написать что-то вроде этого:

var propertyName = GetPropertyName(
    () => myObject.AProperty); // returns "AProperty"
person Jacob    schedule 07.09.2010
comment
+1 за использование Expression; Я так не понял вопроса. - person Ondrej Tucny; 08.09.2010
comment
+1 за Выражение. Я просто сошел с ума от этого! Большое спасибо, чувак ... (Кстати, если бы вы могли немного объяснить мне синтаксис C #, потому что это звучит довольно продвинуто, я должен признать, что на самом деле я не понял всего этого, хотя это работает как шарм) - person Mehdi LAMRANI; 20.01.2011
comment
Синтаксис немного странный. Синтаксис выражений такой же, как синтаксис лямбда-выражений; зависит от типа параметра в вызываемом методе. Если () => myObject.AProperty был лямбда-выражением, а AProperty имел тип int, его тип в основном преобразуется в метод без параметров (), который возвращает => int (неявно определяется посредством статической типизации), что эквивалентно Func<int>. Поскольку GetPropertyName принимает Expression, тип параметра вместо этого преобразуется в Expression<Func<int>>. - person Jacob; 20.01.2011
comment
Спасибо за хорошее решение. Мой вопрос: могу ли я реализовать это, например, myObject.AProperty.GetPropertyName () с методами расширения? - person masoud ramezani; 17.05.2011

В C # 6.0 (Visual Studio 2015) теперь можно использовать оператор nameof, например:

var obj = new MyObject();
string propertyName = nameof(obj.Property);
string methodName = nameof(obj.Method);
string directPropertyName = nameof(MyObject.Property);
string directMethodName = nameof(MyObject.Method);
person saluce    schedule 24.07.2015
comment
Это действительно отличный метод. - person Gandalf458; 30.03.2017
comment
ОП, если вы все еще там, вы можете повторно выбрать принятый ответ? - person William T. Mallard; 28.08.2018

PropertyInfo.Name

person dtb    schedule 07.09.2010

Если кому-то это нужно ... вот версия ответа VB .NET:

Public Shared Function GetPropertyName(Of t)(ByVal PropertyExp As Expression(Of Func(Of t))) As String
   Return TryCast(PropertyExp.Body, MemberExpression).Member.Name
End Function

Использование:

Dim name As String = GetPropertyName(Function() (New myObject).AProperty)
person TKTS    schedule 10.01.2011
comment
Спасибо, TKTS, ваш ответ отличный, и это код C # этой общедоступной статической строки синтаксиса GetPropertyName ‹t› (Выражение ‹Func ‹t›› PropertyExp) {return (PropertyExp.Body as MemberExpression) .Member.Name; } строка name = GetPropertyName (() = ›(новые Задачи ()). Заголовок); - person Ahmad Hindash; 03.05.2015

точно правильный ответ, который написан TKTS, и здесь я просто хочу преобразовать его синтаксис в C #

public static string GetPropertyName<t>(Expression<Func<t>> PropertyExp)
{
return (PropertyExp.Body as MemberExpression).Member.Name;
}

и использование этого кода аналогично приведенному ниже примеру:

string name = GetPropertyName(() => (new Tasks()).Title);

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

Спасибо ТКЦ ..

person Ahmad Hindash    schedule 03.05.2015

Я использовал версию, предоставленную Джейкобом, но иногда она давала исключение. Это было потому, что гипс был недействительным. Эта версия решила проблему:

    public static string GetPropertyName<T>(this Expression<Func<T>> propertyExpression)
    {
        ConstantExpression cExpr = propertyExpression.Body as ConstantExpression;
        MemberExpression mExpr = propertyExpression.Body as MemberExpression;

        if (cExpr != null)
            return cExpr.Value.ToString();
        else if (mExpr != null)
            return mExpr.Member.Name;

        else return null;
    }
person Michael Bahig    schedule 15.12.2013

myClassInstance.GetType().GetProperties() дает вам PropertyInfo экземпляров для всех общедоступных свойств для типа myClassInstance. (См. MSDN для документации и других перегрузок.) «PropertyInfo.Name »- фактическое название собственности. Если вы уже знаете имя свойства, используйте GetProperty(name) для получения его объекта PropertyInfo (см. MSDN снова).

person Ondrej Tucny    schedule 07.09.2010