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

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

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

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

var myInput = "input";

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

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

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

3 ответа

Решение

Решение до C# 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);
    }
}

C# 6.0 и выше решение

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

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

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

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

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

С другой стороны,

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 будет медленнее, на мой вкус. Чтобы получить имя параметра и значение вместе за один раз, посмотрите мой ответ

Другие вопросы по тегам