NameOf (C# 6)

Want to learn about other C# 6 features? Check out the full list of articles & source code on GitHub.
nameof is a fantastic piece of syntactic sugar in C# 6, which aims to solve a major pain: magic strings. A magic string is a type of string in your application that isn’t input/output-related but rather a marker or used for comparison. For example, you might do role checking with something like this:
if (role == "admin")
{
}
The issue with this string "admin" is that there is no compiler checking for it. That means if you mistype the content, you won’t know it’s wrong until the app fails. The second issue is that refactoring tools don’t work with them—so if you change "admin" to "administrator" in one place, there’s no way tools can find and update all instances throughout your app, and it breaks again when you run it.
A lot of the time, you can clean this up with enums or objects. For example, we can improve our role scenario by checking against an enum:
if (role == Roles.Admin.ToString())
{
}
This no longer suffers from the two issues listed above 😊.
Members & Magic Strings
The problem remains with magic strings that refer to members (fields, properties, methods, types, etc.). In the first example, we have a magic string pointing to the Age property:
public int Age
{
get { return age; }
set
{
age = value;
RaisePropertyChanged("Age");
}
}
For the second example, we have a magic string pointing to a class Track:
var type = Type.GetType("Track");
And finally, our third example involves checking a field for null and raising an exception with the correct field name:
private void RaisePropertyChanged(string propertyChanged)
{
if (propertyChanged == null)
{
throw new ArgumentNullException("propertyChanged");
}
// do stuff
}
All of these examples suffer from the same two problems—no compile-time checks and no refactoring support—but until now, there hasn’t been an effective way to clean them up.
nameof
The goal of the new nameof keyword is to solve this specific type of magic string—those that refer to members in code. By using nameof, we can rewrite the above examples like this:
// example 1
public int Age
{
get { return age; }
set
{
age = value;
RaisePropertyChanged(nameof(Age));
}
}
// example 2
var type = Type.GetType(nameof(Track));
// example 3
private void RaisePropertyChanged(string propertyChanged)
{
if (propertyChanged == null)
{
throw new ArgumentNullException(nameof(propertyChanged));
}
// do stuff
}
Notice we’ve eliminated the strings entirely! This means if you mistype a member name at compile time, you’ll get an error.
We also get full refactoring support, since Visual Studio and other refactoring tools can now identify that it’s a member and replace/rename as needed.
More Sugar
As mentioned earlier, this is just syntactic sugar—the compiler does clever tricks for us. All nameof does is instruct the compiler to convert a member to a string, so the output is the same as before—just safer.
I recommend the TryRoslyn website, which is fantastic for experimenting with C# 6. It also shows decompiled code side by side, demonstrating how the syntactic sugar works:
What Does It Output?
In the first set of examples, we looked at simple members, but what if we have something more complex—like a namespace or a class & property? In those cases, it outputs the last part each time:
nameof(Track.Band); // Class.Property → outputs: Property, in this case 'Band'
nameof(System.Configuration); // Namespace → outputs: Last namespace, in this case 'Configuration'
nameof(List); // List + Generics → outputs: The type of the object, in this case 'List'
nameof(this.field); // `this` keyword + field → outputs the field name 'field'
What Isn’t Supported
nameof isn’t a solution for everything in .NET, and there’s a lot it won’t handle. Here are some examples:
nameof(f()); // where `f` is a method → you could use `nameof(f)` instead
nameof(c._Age); // where `c` is a different class and `_Age` is private → nameof can't break accessor rules
nameof(List<>); // List<> isn't valid C# anyway
nameof(default(List<int>)); // default returns an instance, not a member
nameof(int); // `int` is a keyword, not a member → you could do `nameof(Int32)`
nameof(x[2]); // returns an instance using an indexer, so not a member
nameof("hello"); // a string isn't a member
nameof(1+2); // an `int` isn't a member
Is This a Replacement for CallerMemberName?
I’ve written about a fantastic .NET 4.5 feature called CallerMemberName. To recap: it’s a way to attribute a method parameter and have the runtime set its value to the name of the calling member.
In the following example, the output will be Main, matching the name of the calling method:
private static void Main(string[] args)
{
WhoCallsMe();
}
static void WhoCallsMe([CallerMemberName] string caller = "")
{
Console.WriteLine(caller);
}
This seems similar to nameof, but there are fundamental differences. Most importantly:
nameofworks at compile time.CallerMemberNameworks at runtime.
This means one method in the example can work with multiple callers—i.e., if you call it from a different member, it will output the correct name. There’s no way to do that with nameof, since it produces hardcoded values.
While there’s some overlap, in cases like XAML + RaisePropertyChanged, you could choose either based on preference—but these two features have their differences. There are times where CallerMemberName is the only viable option.