A deeper look at C# 6's nameof expression

Posted on Tuesday, 29 Dec 2015

Like many developers I'm somewhat reluctant to use string literals or magic strings to reference variables, types or members due to the increased chances of introducing bugs into a codebase and the cost of maintainability. Wherever possible I will always try my best to avoid using them if the solution doesn't outweigh the cost. Whilst string literals can most often be avoided, one area that C# never had an easy solution for the problem was in areas such as referencing variables when throwing exceptions.

With the release of C# 6 this problem and instances like can be easily avoided with the introduction of the nameof expression.

C#6 nameof expression

The nameof expression is a simple solution to the problem, see the follow snippets from the MSDN docs for an example of how the nameof expression can be is used:

void f(string s) {
    if (s == null) throw new ArgumentNullException(nameof(s));
}

Using the nameof expression in Razor becomes especially helpful:

<%= Html.ActionLink("Sign up", @typeof(UserController), @nameof(UserController.SignUp)) %>

What's happening under the hood?

As it's always a good idea to understand how things are interpreted when compiled, let's take a look and see exactly what happens to the following code sample:

public class Class1
{
    public void Output(string myString)
    {
        if (myString == null)
        {
            throw new ArgumentNullException(nameof(myString));
        }
    }
}

When we use a tool like JetBrain's free decompiler DotPeek to take a look at the decompiled source you can see that the property passed into the nameof expression has now been evaluated at compile time and converted into a string literal representation of the parameter:

public class Class1
{
	public void Output(string myString)
	{
		bool flag = myString == null;
		if (flag)
		{
			throw new ArgumentNullException("myString");
		}
	}
}

The result is the exact equivalent of what you'd normally do without the nameof expression - except this time you have the added benefit of compile time safety, rather than having to rely on magic strings (something that's extremely helpful when using refactoring tools to rename classes, properties or methods).

With this in mind, that means if we were to take the following with and without nameof examples and view the IL code generated then they should be exactly the same:

// With nameof expression:
string myString = "Hello World";
throw new ArgumentNullException(nameof(myString));

// Without nameof expression:
string myString = "Hello World";
throw new ArgumentNullException("myString");

IL code generated when using the nameof expression:

IL_0000:  nop
IL_0001:  ldstr      "Hello World"
IL_0006:  stloc.0
IL_0007:  ldstr      "myString"
IL_000c:  newobj     instance void [mscorlib]System.ArgumentNullException::.ctor(string)
IL_0011:  throw

IL code generated when not using the nameof expression:

IL_0000:  nop
IL_0001:  ldstr      "Hello World"
IL_0006:  stloc.0
IL_0007:  ldstr      "myString"
IL_000c:  newobj     instance void [mscorlib]System.ArgumentNullException::.ctor(string)
IL_0011:  throw

We can see that the output is identical.

If that isn't proof enough that you should favour using the nameof expression over magic strings then I don't know what is!

Update:
If you're keen to go even further into the nameof expression then @ErikSchierboom has written an extremely indepth look at what's happening under the bonnet in his C# 6 under the hood: nameof operator article that I'd highly recommend reading.

Back