get name of a variable or parameter [duplicate]

I would like to get the name of a variable or parameter:

For example if I have:

var myInput = "input";

var nameOfVar = GETNAME(myInput); // ==> nameOfVar should be = myInput

void testName([Type?] myInput)
{
   var nameOfParam = GETNAME(myInput); // ==> nameOfParam should be = myInput
}

How can I do it in C#?


Solution 1:

Pre C# 6.0 solution

You can use this to get a name of any provided member:

public static class MemberInfoGetting
{
    public static string GetMemberName<T>(Expression<Func<T>> memberExpression)
    {
        MemberExpression expressionBody = (MemberExpression)memberExpression.Body;
        return expressionBody.Member.Name;
    }
}

To get name of a variable:

string testVariable = "value";
string nameOfTestVariable = MemberInfoGetting.GetMemberName(() => testVariable);

To get name of a parameter:

public class TestClass
{
    public void TestMethod(string param1, string param2)
    {
        string nameOfParam1 = MemberInfoGetting.GetMemberName(() => param1);
    }
}

C# 6.0 and higher solution

You can use the nameof operator for parameters, variables and properties alike:

string testVariable = "value";
string nameOfTestVariable = nameof(testVariable);

Solution 2:

What you are passing to GETNAME is the value of myInput, not the definition of myInput itself. The only way to do that is with a lambda expression, for example:

var nameofVar = GETNAME(() => myInput);

and indeed there are examples of that available. However! This reeks of doing something very wrong. I would propose you rethink why you need this. It is almost certainly not a good way of doing it, and forces various overheads (the capture class instance, and the expression tree). Also, it impacts the compiler: without this the compiler might actually have chosen to remove that variable completely (just using the stack without a formal local).

Solution 3:

Alternatively,

1) Without touching System.Reflection namespace,

GETNAME(new { myInput });

public static string GETNAME<T>(T myInput) where T : class
{
    if (myInput == null)
        return string.Empty;

    return myInput.ToString().TrimStart('{').TrimEnd('}').Split('=')[0].Trim();
}

2) The below one can be faster though (from my tests)

GETNAME(new { variable });
public static string GETNAME<T>(T myInput) where T : class
{
    if (myInput == null)
        return string.Empty;

    return typeof(T).GetProperties()[0].Name;
}

You can also extend this for properties of objects (may be with extension methods):

new { myClass.MyProperty1 }.GETNAME();

You can cache property values to improve performance further as property names don't change during runtime.

The Expression approach is going to be slower for my taste. To get parameter name and value together in one go see this answer of mine