Оценивается ли 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так же эффективно, как объявление строковой переменной.