Оценивается ли nameof () во время компиляции?


В C# 6, Вы можете использовать nameof() оператор для получения строки, содержащей имя переменной или типа.

это оценивается во время компиляции или во время выполнения с помощью некоторого API Roslyn?

Вы можете прочитать о nameof() оператор официальные дискуссии указал на принято отвечать или специальный пост в моем блоге. ВКЛ 2000things.com, Вы можете найти его описание и пример его использования.

2 106

2 ответа:

да. nameof() вычисляется во время компиляции. Глядя на последнюю версию спецификации:

имя выражения является константой. Во всех случаях, имя(...) есть вычисляется во время компиляции для получения строки. Его аргумент не вычисляется во время выполнения и считается недостижимым кодом (однако он не выдает предупреждение "недостижимый код").

С оператор nameof-v5

вы можете увидеть, что с в этом примере TryRoslyn где это:

public class Foo
{
    public void Bar()
    {
        Console.WriteLine(nameof(Foo));
    }
}

компилируется и декомпилируется в это:

public class Foo
{
    public void Bar()
    {
        Console.WriteLine("Foo");
    }
}

его эквивалент времени выполнения:

public class Foo
{
    public void Bar()
    {
        Console.WriteLine(typeof(Foo).Name);
    }
}

как уже упоминалось в комментариях, это означает, что при использовании nameof для параметров типа в универсальном типе не ожидайте получить имя фактического динамического типа, используемого в качестве параметра типа, а не только имя параметра типа. Так вот:

public class Foo
{
    public void Bar<T>()
    {
        Console.WriteLine(nameof(T));
    }
}

будет стань это:

public class Foo
{
    public void Bar<T>()
    {
        Console.WriteLine("T");
    }
}

Я хотел обогатить ответ, предоставленный @I3arnon С доказательством того, что оно вычисляется во время компиляции.

предположим, что я хочу напечатать имя переменной в консоли с помощью nameof оператор:

 var firstname = "Gigi";
 var varname = nameof(firstname);
 Console.WriteLine(varname); // Prints "firstname" to the console

когда вы проверите сгенерированный MSIL, вы увидите, что он эквивалентен объявлению строки, потому что ссылка на объект строки помещается в стек с помощью ldstr оператор:

IL_0001: ldstr "Gigi"
IL_0006: stloc.0
IL_0007: ldstr "firstname"
IL_000c: stloc.1
IL_000d: ldloc.1
IL_000e: call void [mscorlib]System.Console::WriteLine(string)

вы обратите внимание, что объявление строки firstname и использование nameof оператор генерирует тот же код в MSIL, что означает nameof так же эффективно, как объявление строковой переменной.