Stats

Contributors: 20 Wednesday, December 7, 2016
Licensed under: CC-BY-SA
Not affiliated with Stack Overflow
Rip Tutorial: riptutorial@gmail.com
Roadmap: roadmap

Operator nameof

Download c# eBook

Example

The nameof operator returns the name of a code element as a string. This is useful when throwing exceptions related to method arguments and also when implementing INotifyPropertyChanged.

public string SayHello(string greeted)
{
    if (greeted == null)
        throw new ArgumentNullException(nameof(greeted));
    
    Console.WriteLine("Hello, " + greeted);
}

The nameof operator is evaluated at compile time and changes the expression into a string literal. This is also useful for strings that are named after their member that exposes them. Consider the following:

public static class Strings
{
    public const string Foo = nameof(Foo); // Rather than Foo = "Foo"
    public const string Bar = nameof(Bar); // Rather than Bar = "Bar"
}

Since nameof expressions are compile-time constants, they can be used in attributes, case labels, switch statements, and so on.


It is convenient to use nameof with Enums. Instead of:

Console.WriteLine(Enum.One.ToString());

it is possible to use:

Console.WriteLine(nameof(Enum.One))

The output will be One in both cases.


The nameof operator can access non-static members using static-like syntax. Instead of doing:

string foo = "Foo";
string lengthName = nameof(foo.Length);

Can be replaced with:

string lengthName = nameof(string.Length);

The output will be Length in both examples. However, the latter prevents the creation of unnecessary instances.


Although the nameof operator works with most language constructs, there are some limitations. For example, you cannot use the nameof operator on open generic types or method return values:

public static int Main()
{   
    Console.WriteLine(nameof(List<>)); // Compile-time error
    Console.WriteLine(nameof(Main())); // Compile-time error
}

Furthermore, if you apply it to a generic type, the generic type parameter will be ignored:

Console.WriteLine(nameof(List<int>));  // "List"
Console.WriteLine(nameof(List<bool>)); // "List"

For more examples, see this topic dedicated to nameof.


Workaround for previous versions (more detail)

Although the nameof operator does not exist in C# for versions prior to 6.0, similar functionality can be had by using MemberExpression as in the following:

6.0

Expression:

public static string NameOf<T>(Expression<Func<T>> propExp)
{
    var memberExpression = propExp.Body as MemberExpression;
    return memberExpression != null ? memberExpression.Member.Name : null;
}

public static string NameOf<TObj, T>(Expression<Func<TObj, T>> propExp)
{
    var memberExpression = propExp.Body as MemberExpression;
    return memberExpression != null ? memberExpression.Member.Name : null;
}

Usage:

string variableName = NameOf(() => variable);
string propertyName = NameOf((Foo o) => o.Bar);

Note that this approach causes an expression tree to be created on every call, so the performance is much worse compared to nameof operator which is evaluated at compile time and has zero overhead at runtime.