Оценивается ли nameof () во время компиляции?
В C# 6, Вы можете использовать nameof()
оператор для получения строки, содержащей имя переменной или типа.
это оценивается во время компиляции или во время выполнения с помощью некоторого API Roslyn?
Вы можете прочитать о nameof()
оператор официальные дискуссии указал на принято отвечать или специальный пост в моем блоге. ВКЛ 2000things.com, Вы можете найти его описание и пример его использования.
2 ответа:
да.
nameof()
вычисляется во время компиляции. Глядя на последнюю версию спецификации:имя выражения является константой. Во всех случаях, имя(...) есть вычисляется во время компиляции для получения строки. Его аргумент не вычисляется во время выполнения и считается недостижимым кодом (однако он не выдает предупреждение "недостижимый код").
вы можете увидеть, что с в этом примере 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
так же эффективно, как объявление строковой переменной.