How to get current property name via reflection?

Viewed 32558

I would like to get property name when I'm in it via reflection. Is it possible?

I have code like this:

public CarType Car
{
    get { return (Wheel) this["Wheel"];}
    set { this["Wheel"] = value; }
}

And because I need more properties like this I would like to do something like this:

public CarType Car
{
    get { return (Wheel) this[GetThisPropertyName()];}
    set { this[GetThisPropertyName()] = value; }
}
8 Answers

Since properties are really just methods you can do this and clean up the get_ returned:

class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            var x = p.Something;
            Console.ReadLine();
        }

        public string Something
        {
            get
            {
                return MethodBase.GetCurrentMethod().Name;
            }
        }
    }

If you profile the performance you should find MethodBase.GetCurrentMethod() is miles faster than StackFrame. In .NET 1.1 you will also have issues with StackFrame in release mode (from memory I think I found it was 3x faster).

That said I'm sure the performance issue won't cause too much of a problem- though an interesting discussion on StackFrame slowness can be found here.

I guess another option if you were concerned about performance would be to create a Visual Studio Intellisense Code Snippet that creates the property for you and also creates a string that corresponds to the property name.

I'd like to know more about the context in which you need it since it seems to me that you should already know what property you are working with in the property accessor. If you must, though, you could probably use MethodBase.GetCurrentMethod().Name and remove anything after get_/set_.

Update:

Based on your changes, I would say that you should use inheritance rather than reflection. I don't know what data is in your dictionary, but it seems to me that you really want to have different Car classes, say Sedan, Roadster, Buggy, StationWagon, not keep the type in a local variable. Then you would have implementations of methods that do the proper thing for that type of Car. Instead of finding out what kind of car you have, then doing something, you then simply call the appropriate method and the Car object does the right thing based on what type it is.

 public interface ICar
 {
      void Drive( decimal velocity, Orientation orientation );
      void Shift( int gear );
      ...
 }

 public abstract class Car : ICar
 {
      public virtual void Drive( decimal velocity, Orientation orientation )
      {
          ...some default implementation...
      }

      public abstract void Shift( int gear );

      ...
 }

 public class AutomaticTransmission : Car
 {
       public override void Shift( int gear )
       {
          ...some specific implementation...
       }
 }

 public class ManualTransmission : Car
 {
       public override void Shift( int gear )
       {
          ...some specific implementation...
       }
 }

Use MethodBase.GetCurrentMethod() instead!

Reflection is used to do work with types that can't be done at compile time. Getting the name of the property accessor you're in can be decided at compile time so you probably shouldn't use reflection for it.

You get use the accessor method's name from the call stack using System.Diagnostics.StackTrace though.

string GetPropertyName()
{
    StackTrace callStackTrace = new StackTrace();
    StackFrame propertyFrame = callStackTrace.GetFrame(1); // 1: below GetPropertyName frame
    string properyAccessorName = propertyFrame.GetMethod().Name;

    return properyAccessorName.Replace("get_","").Replace("set_","");
}

Solution # 1

var a = nameof(SampleMethod);    //a == SampleMethod
var b = nameof(SampleVariable);  //b == SampleVariable
var c = nameof(SampleProperty);  //c == SampleProperty

Solution # 2

MethodBase.GetCurrentMethod().Name; // Name of method in which you call the code
MethodBase.GetCurrentMethod().Name.Replace("set_", "").Replace("get_", ""); // current Property

Solution # 3

from StackTrace:

public static class Props
{
    public static string CurrPropName => 
         (new StackTrace()).GetFrame(1).GetMethod().Name.Replace("set_", "").Replace("get_", "");

    public static string CurrMethodName => 
        (new StackTrace()).GetFrame(1).GetMethod().Name;
}

you just need to call Props.CurrPropName or Props.CurrMethodName


Solution # 4

Solution for .NET 4.5+:

public static class Props
{
    public static string GetCallerName([System.Runtime.CompilerServices.CallerMemberName] String propertyName = "")
    {
         return propertyName;
    }
}

usage: Props.GetCallerName();

Yes, it is!

string test = "test string";
Type type = test.GetType();

PropertyInfo[] propInfos = type.GetProperties();
for (int i = 0; i < propInfos.Length; i++) 
{
    PropertyInfo pi = (PropertyInfo)propInfos.GetValue(i);
    string propName = pi.Name;
}

Try using System.Diagnostics.StackTrace to reflect on the call stack. The property should be somewhere in the call stack (probably at the top if you're calling it directly from the property's code).

Related