Home > Articles > Programming > C#

The New nameof Expressions in C# 6: Painless Conversion of Symbols to Strings

  • Print
  • + Share This
Translating symbol names into text is common in modern code. The task isn't exactly odious, but it still takes time, it's tedious, and it's easy to make mistakes. Bill Wagner, author of Effective C#: 50 Specific Ways to Improve Your C#, Second Edition, happily skips all that work (and the associated runtime costs) with the help of the new nameof expression in C# 6.
From the author of

One of the more specific of the new features in C# 6, the nameof expression replaces a C# symbol with the string representation of that symbol. Many of the idioms we use in modern development—reflection, late binding, wire-transfer protocols like JSON, logging scenarios—require us to translate symbol names into text. Copying the symbol name and putting it inside quotes to create a string; it's so easy that we do it without thinking—and that's the problem. When we write code without thinking, we make mistakes. Sometimes we catch those mistakes immediately. Sometimes we catch them with tests. And sometimes we don't catch them until after the product ships.

In previous versions of C#, options were limited. We copied symbol names, or we wrote dynamic code that used expressions and reflection to find the name of a symbol. That dynamic code was error-prone and came with significant runtime performance costs. The Windows 8 Store templates used the CallerMemberName attribute to build a reusable feature that would raise the correct PropertyChanged events in a view. Even this had runtime costs.

Overall, we expended a lot of brainpower to convert C# symbols to strings. All those different techniques used a runtime conversion, and therefore came with significant runtime costs. Converting symbols to strings started to look like a great language feature.

Introducing nameof

The new nameof expression in C# 6 addresses these concerns. It takes an expression and evaluates to the string representation of the local name of that expression. The canonical example is raising the PropertyChanged event in a class that implements INotifyPropertyChanged:

public class Person : INotifyPropertyChanged
    public string FirstName
            return firstName;
            if (value != firstName)
                firstName = value;
                    new PropertyChangedEventArgs(nameof(FirstName)));
    private string firstName;

    public event PropertyChangedEventHandler PropertyChanged;

    // more elided

In the example above, the nameof expression generates the string used in the constructor to the PropertyChangedEventArgs object. (Notice that I'm also using the new ?. operator I discussed in "Using the New Null Conditional Operator in C# 6.") Using the nameof operator eliminates any chance of mistyping the property name. If I mistype the symbol name, the compiler complains, and I must fix it. The symbol has semantic meaning.

Making the compiler prevent you from mistyping a property name is only the beginning. Equally important, any static analysis tools you use can also benefit from having the symbol information, rather than just a text string. Figure 1 shows the code from the preceding example, after I've used the Rename refactoring (F2) to change the property name from "FirstName" to "GivenName". Notice that the refactoring tool finds and highlights the symbol in the nameof expression. Because it's a valid C# symbol, not a string literal, the symbol participates in all of the analysis.

The refactoring tools and the compiler validation show why this feature is important for modern developers. The size of our modern codebases mandates using software tools to help us manage our software development activities. Those tools often rely on static analysis of our software to understand our code and to suggest where we may have made mistakes.

Also, unlike earlier attempts to convert symbols to human-readable text, the nameof expression involves no runtime cost. The nameof expression is evaluated at compile time, and the generated code contains the replacement text.

Valid nameof Expressions

In the examples to this point, I've used the property name as the expression. You can qualify the expression with the type name, if that's more readable to you:

    new PropertyChangedEventArgs(nameof(Person.FirstName)));

The compiler generates text for the rightmost name. In this case, it generates "FirstName", not "Person.FirstName". It follows that you can use the fully qualified name, including any namespaces:

    new PropertyChangedEventArgs(nameof(ExampleNamespace.ExampleCode.Person.FirstName)));

The result is still the string "FirstName".

The argument to nameof must resolve to a named expression. I've used property names in the examples so far, but several other named expressions are also valid. You can use local variables. Non-generic class names, struct names, and delegate types are also legal.

Anonymous types, numeric literals, and string literals, on the other hand, are not legal. They produce CS 8081, "Expression does not have a name". The same is true for lambda expressions.

Generics are an interesting case. You can use closed generic types anywhere, if every type parameter has been specified. For example:


This expression evaluates to "List". The type parameters are omitted from the generated string.

You can use a generic type definition (where the type parameters are placeholders, such as in List<T>) only inside a generic type definition that has the same named-type parameter. I couldn't use List<T> inside the Person class shown in my examples, but I could use IEnumerable<T> inside a class like List<T>, where the 'T' type parameter has been declared.

Those rules might seem a bit hard to comprehend when written in English, but they're reasonable as you write code. Just remember that the argument to the nameof expression must have a name, and the symbol must resolve at compile time. Just as you can't declare a variable of the type List<T> outside a generic definition (where T is a type parameter), you can't use List<T> in a nameof expression when T has not been defined.

Some Initial Guidance on nameof, and a Look into the Future

As with the other new features I've discussed in previous articles, I've made it a habit to use the new feature in new code that I write. It helps me to create correct code and, in this case, to avoid simple mistakes that come from translating program symbols to text by hand.

However, with this feature, I'm not updating my existing code very aggressively. I don't update existing code with the nameof expression unless I already have tests surrounding that code, to verify that its behavior is correct. It may seem a reasonable assumption to correct strings that you see in code. But in many cases a text string may be different from a program symbol name for good reason. It may be easy to make all those changes. However, be careful to make sure that the text is intended to match the symbol. It may be a coincidence, rather than part of a design. That means being cautious about any changes.

I'm more excited about what might happen in future releases. In Visual Studio 2015, any of the tools and features work with C#—and only C#. In future releases, I'd like to see the tools extend to places where C# interacts with other languages. This could be a huge help in XAML bindings, or bindings in Razor syntax. One day, maybe it could even extend to matching names in C# with bindings in view models in an Angular-based application. None of these features are promised, but they would be welcome.

  • + Share This
  • 🔖 Save To Your Account