Получить имя переменной или параметра

Возможный дубликат:
Поиск имени переменной, переданного функции в С#

Я хотел бы получить имя переменной или параметра:

Например, если у меня есть:

var myInput = "input";

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

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

Как я могу сделать это на С#?

Ответы

Ответ 1

Решение для С# 6.0

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

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

Чтобы получить имя переменной:

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

Чтобы получить имя параметра:

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

Решение С# 6.0 и выше

Вы можете использовать оператор nameof для параметров, переменных и свойств:

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

Ответ 2

То, что вы переходите на GETNAME, - это значение myInput, а не определение myInput. Единственный способ сделать это - с помощью выражения лямбда, например:

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

и действительно есть примеры доступных. Однако! Это пахнет чем-то очень неправильным. Я бы предложил вам переосмыслить , почему вам нужно это. Это почти наверняка не очень хороший способ сделать это, и накладывает различные накладные расходы (экземпляр класса захвата и дерево выражений). Кроме того, это влияет на компилятор: без этого компилятор действительно мог бы полностью удалить эту переменную (просто используя стек без формального локального).

Ответ 3

В качестве альтернативы

1) Не касаясь пространства имен System.Reflection,

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) Ниже ниже может быть быстрее (из моих тестов)

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

Вы также можете расширить это для свойств объектов (может быть с помощью методов расширения):

new { myClass.MyProperty1 }.GETNAME();

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

Подход Expression будет медленнее для моего вкуса. Чтобы получить имя и значение параметра за один раз, см. этот мой ответ