Is nameof() evaluated at compile-time?

Gigi picture Gigi · Oct 26, 2014 · Viewed 16k times · Source

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?

Answer

i3arnon picture i3arnon · Oct 26, 2014

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<T>()
    {
        Console.WriteLine(nameof(T));
    }
}

Will become this:

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