C#: is there a way to access the name of the current field?

1.2k Views Asked by At

In C#, I am defining a static field of a specific class. From within the class, I want to be able to display the name of the static field, pretty much like this:

public class Unit {
  public string NameOfField { get { return ...; } }
}

public static Unit Hectare = new Unit();

If I now access:

Hectare.NameOfField

I want it to return:

Hectare

I know there is a static function System.Reflection.MethodBase.GetCurrentMethod(), but as far as I can tell there is no way to get the name of the instance containing this current method?

There is also the System.RuntimeFieldHandle structure, but I have not been able to identify any GetCurrentFieldHandle() method.

I am not sure if I am missing something obvious?

Any help on this is very much appreciated.

4

There are 4 best solutions below

0
On BEST ANSWER

Thanks everyone who has taken the time to answer and discuss my question.

Just to let you know, I have implemented a solution that is sufficient for my needs. The solution is not general, and it has some pitfalls, but I'd thought I share it anyway in case it can be of help to someone else.

This is in principle what the class that is used when defining fields looks like:

public class Unit : IUnit {
  public NameOfField { get; set; }
  ...
}

As you can see, the class implements the IUnit interface, and I have provided a public setter in the NameOfField property.

The static fields are typically defined like this within some containing class:

public static Unit Hectare = new Unit();

My solution is to set the NameOfField property through reflection before the field is used in the implementation. I do this through a static constructor (that of course needs to be invoked before the Unit fields are accessed. I use Linq to traverse the executing assembly for the relevant fields, and when I have detected these fields (fields which type implements the IUnit interface), I set the NameOfField property for each of them using the Any extension method:

Assembly.GetExecutingAssembly().GetTypes().
  SelectMany(type => type.GetFields(BindingFlags.Public | BindingFlags.Static)).
  Where(fieldInfo => fieldInfo.FieldType.GetInterfaces().Contains(typeof(IUnit))).
  Any(fieldInfo =>
  {
    ((IUnit)fieldInfo.GetValue(null)).NameOfField= fieldInfo.Name;
    return false;
  });

There are some shortcomings with this approach:

  • The static constructor has to be invoked through manual intervention before any Unit fields can be accessed
  • The NameOfField setter is public. In my case this is no problem, but it might be when applied in other scenarios. (I assume that the setter could be made private and invoked through further reflection, but I have not taken the time to explore that path further.)
  • ... ?

Either way, maybe this solution can be of help to someone else than me.

3
On

You should not count on variable names in you developments as they do not exits at runtime.

It's better to initialize Unit with a name directly:

public class Unit {

  public Unit(string name)
  {
     NameOfField = name;
  }
  public string NameOfField { get; private set;} }
}

public static Unit Hectare = new Unit("Hectare");
1
On

Only way around this will be to store that information in the class:

public static Unit Hectare = new Unit("Hectare");

When your code is compiled all variable names are lost and replaced by internal references. There is no way to get that name again.

2
On

You can use Reflection to obtain class Fields and properties. Like below:

Suppose you have class with one property:

class Test
{
    public static string MySupperField
    {
        get
        {
            return "Some symbols here";
        }
    }
}

......

You can read the property name in such way:

public string[] GetClassStaticNames(Type T)
{
    string[] names;

    System.Reflection.PropertyInfo[] props = T.GetProperties(); // This will return only properties not fields! For fields obtaining use T.GetFields();

    names = new string[props.Count()];
    for (int i = 0; i < props.Count(); i++)
    {
        names[i] = props[i].Name;
    }

    return names;
}

Hope this will help.

[EDIT]
Returning to your question - No you cant obtain name of current variable.
What you are asking about cant be done because of classes nature, they are objects in memory and reference to one object can be held in many variables, and when you are requesting value of instance field or property it will be actually performed operation with object in memory not with variable wich holds reference to that object. So obtaining name of variable wich holds reference to current instance have no sence