Get string name of property using reflection
Asked Answered
F

7

55

There is a whole wealth of reflection examples out there that allow you to get either:

  1. All properties in a class
  2. A single property, provided you know the string name

Is there a way (using reflection, TypeDescriptor, or otherwise) to get the string name of a property in a class at runtime, provided all I have is an instance of the class and property?

I have an instance of the class with the property (as well as other properties) that I want to get the string name of (not the getter/setter). I need to do some work on that property using Reflection, but don't want to maintain code with hardcoded string names in case I refactor the property name. Thus, I want to programatically get the name of the property.

I know that I can easily get all the properties in a class using reflection and then get the name of each property. What I'm asking for is a function to give me name of a property, provided I pass it the instance of the property. In other words, how do I find the property I want from the PropertyInfo[] array returned to me from the class.GetType().GetProperty(myProperty) so that I can get the PropertyInfo.Name from it?

Faints answered 7/9, 2010 at 19:6 Comment(2)
How else can you identify the property you want, if not by name?Nikitanikki
possible duplicate of Get property name and type using lambda expressionHennery
S
101

If you already have a PropertyInfo, then @dtb's answer of using PropertyInfo.Name is the right way. If, however, you're wanting to find out which property's code you're currently in, you'll have to traverse the current call stack to find out which method you're currently executing and derive the property name from there.

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);

If you don't have a PropertyInfo object, you can get that from a property expression, like this:

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

To use it, you'd write something like this:

var propertyName = GetPropertyName(
    () => myObject.AProperty); // returns "AProperty"
Softener answered 7/9, 2010 at 19:12 Comment(2)
The syntax is a bit bizarre. The syntax for expressions is just like the syntax for lambda expressions; whether it's one or the other depends on the type of the parameter in the method being called. If () => myObject.AProperty was a lambda expression where AProperty was of type int, its type basically translates to "a method with no parameters () which returns => an int (implicitly determined through static typing), which is equivalent to Func<int>. Since GetPropertyName takes an Expression, the parameter's type translates to Expression<Func<int>> instead.Softener
Thank you for your good solution. My question is that: can I implement this like : myObject.AProperty.GetPropertyName() with extension methods ?Wiley
C
67

With C# 6.0 (Visual Studio 2015), you can now use the nameof operator, like this:

var obj = new MyObject();
string propertyName = nameof(obj.Property);
string methodName = nameof(obj.Method);
string directPropertyName = nameof(MyObject.Property);
string directMethodName = nameof(MyObject.Method);
Calculous answered 24/7, 2015 at 15:46 Comment(0)
L
19

Use the PropertyInfo.Name class.

Liquidator answered 7/9, 2010 at 19:9 Comment(0)
H
6

In case anyone needs it...here is the VB .NET version of the answer:

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

Usage:

Dim name As String = GetPropertyName(Function() (New myObject).AProperty)
Heterothallic answered 10/1, 2011 at 16:23 Comment(0)
G
3

I want to convert TKTS' answer syntax to C#:

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

and the usage of this code goes like the example as below:

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

An exception could happen when all properties have null values, so care is needed when implementing this code.

Gooey answered 3/5, 2015 at 11:4 Comment(0)
E
1

The version provided by Jacob sometimes gives an exception due to the cast being invalid. This version solves that casting issue:

    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;
    }
Edam answered 15/12, 2013 at 21:20 Comment(0)
P
0

myClassInstance.GetType().GetProperties() gives you PropertyInfo instances for all public properties for myClassInstance's type. (See MSDN for documentation and other overloads.) ´PropertyInfo.Name´ is the actual name of the property. In case you already know the name of the property use GetProperty(name) to retrieve its PropertyInfo object (see MSDN again).

Peptone answered 7/9, 2010 at 19:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.