In C# 6, you can use the nameof()
operator to get a string containing the name of a variable or a type.
Is this evaluated at compile-time, or at runtime via some Roslyn API?
You can read about the nameof()
operator at the official discussion pointed out in the accepted answer, or the dedicated post at my blog. On 2000things.com, you can find its description and example of its use.
Yes. nameof()
is evaluated at compile-time. Looking at the latest version of the specs:
The nameof expression is a constant. In all cases, nameof(...) is evaluated at compile-time to produce a string. Its argument is not evaluated at runtime, and is considered unreachable code (however it does not emit an "unreachable code" warning).
From nameof operator - v5
You can see that with this TryRoslyn example where this:
public class Foo { public void Bar() { Console.WriteLine(nameof(Foo)); } }
Is compiled and decompiled into this:
public class Foo { public void Bar() { Console.WriteLine("Foo"); } }
Its run-time equivalent is:
public class Foo { public void Bar() { Console.WriteLine(typeof(Foo).Name); } }
As was mentioned in the comments, that means that when you use nameof
on type parameters in a generic type, don't expect to get the name of the actual dynamic type used as a type parameter instead of just the type parameter's name. So this:
public class Foo { public void Bar() { Console.WriteLine(nameof(T)); } }
Will become this:
public class Foo { public void Bar() { Console.WriteLine("T"); } }
I wanted to enrich the answer provided by @I3arnon with a proof that it is evaluated at compile-time.
Let's assume i want to print the name of a variable in the Console using the nameof
operator:
var firstname = "Gigi"; var varname = nameof(firstname); Console.WriteLine(varname); // Prints "firstname" to the console
When you check out the MSIL generated you will see that it is equivalent to a string declaration because an object reference to a string gets pushed to the stack using the ldstr
operator:
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)
You will notice that declaring the firstname string and using the nameof
operator generates the same code in MSIL, which means nameof
is as efficient as declaring a string variable.