У C # 6 ви можете використовувати nameof()
оператор, щоб отримати рядок, що містить ім'я змінної чи типу.
Чи оцінюється це під час компіляції або під час виконання через якийсь API Roslyn?
У C # 6 ви можете використовувати nameof()
оператор, щоб отримати рядок, що містить ім'я змінної чи типу.
Чи оцінюється це під час компіляції або під час виконання через якийсь API Roslyn?
Відповіді:
Так. nameof()
оцінюється під час компіляції. Переглядаючи останню версію специфікацій:
Вираз nameof є постійною. У всіх випадках 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)
Ви помітите, що декларування рядка імені та використання nameof
оператора генерує той самий код у MSIL, що означає nameof
настільки ж ефективно, як і оголошення строкової змінної.
nameof
оператор, а не звичайний жорсткий код ?