C# 6.0 has a lot of new features, one of them is nameof operator. Let's see how it's implemented internally and what we can do with it.

This operator will help us get rid of "magic strings" in our code. We all know following use case:

public void Method ( int arg ) { if ( arg < 0 ) { throw new ArgumentOutOfRangeException ( "arg" ) ; } }

With nameof operator we can rewrite code in a nicer way:

public void Method ( int arg ) { if ( arg < 0 ) { throw new ArgumentOutOfRangeException ( nameof ( arg ) ) ; } }

That is! nameof just returns a string representation of variable\method\type\propery\field. This might be very helpful during refactoring, you do not need to worry about string literals in your code anymore :)

The same as String Interpolation and Null Propagation operator, nameof is just a syntax sugar. During compilation process, whole expression will be replaced by a string. Let's see following example:

static void Main ( string [ ] args ) { Console . WriteLine ( nameof ( args ) ) ; }

And IL code:

IL_0001 : ldstr "args" IL_0006 : call void [ mscorlib ] System . Console :: WriteLine ( string )

As we can see in line IL_0001, "args" is pushed on the stack with a ldsrt instruction.

Because it is a "compile-time operator" we cannot use expressions in the nameof operator. Following code will not compile because args.ToString() can be evaluated only in run-time:

Console . WriteLine ( nameof ( args . ToString ( ) . Length ) ) ;

Here are more examples of nameof use:

namespace MyNameSpace { internal enum ETestEnum { FirstValue } internal class Program { private static string privateField ; public static string PublicProperty { get ; set ; } static void Main ( string [ ] args ) { var localVar = 1 ; Console . WriteLine ( nameof ( localVar ) ) ; Console . WriteLine ( nameof ( privateField ) ) ; Console . WriteLine ( nameof ( PublicProperty ) ) ; Console . WriteLine ( nameof ( args ) ) ; Console . WriteLine ( nameof ( Main ) ) ; Console . WriteLine ( nameof ( Program ) ) ; Console . WriteLine ( nameof ( MyNameSpace ) ) ; Console . WriteLine ( nameof ( Action < Program , Program > ) ) ; Console . WriteLine ( nameof ( Action < Program , Program > . Method ) ) ; Console . WriteLine ( nameof ( GenericMethod ) ) ; Console . WriteLine ( nameof ( ETestEnum ) ) ; Console . WriteLine ( nameof ( ETestEnum . FirstValue ) ) ; } private static void GenericMethod < T > ( ) { } } }

Let's take a closer look at generic classes and methods. In case of Action<Program, Program> we will see only Action. The same with generic methods.

Also, if you want to get enum's value name you should use nameof operator instead of .ToString() method.

Console . WriteLine ( nameof ( ETestEnum . FirstValue ) ) ; Console . WriteLine ( ETestEnum . FirstValue . ToString ( ) ) ;

If we look at IL code we will see why nameof is preferable in this case:

IL_004e : ldstr "FirstValue" IL_0053 : call void [ mscorlib ] System . Console :: WriteLine ( string ) IL_0058 : nop IL_0059 : ldc . i4 . 0 IL_005a : stloc . 0 IL_005b : ldloca . s V_0 IL_005d : constrained . MyNameSpace . ETestEnum IL_0063 : callvirt instance string [ mscorlib ] System . Object :: ToString ( ) IL_0068 : call void [ mscorlib ] System . Console :: WriteLine ( string )

As you can see, string constant (IL_004e) will be much more efficient than callvirt instruction (IL_0063).

Everyday use cases

INotifyPropertyChanged

public int Property { get { return this . p ; } set { this . p = value ; PropertyChanged ( this , new PropertyChangedEventArgs ( nameof ( this . p ) ) ; } }

Parameters Validation

void Method ( string arg ) { if ( arg == null ) { throw new ArgumentNullException ( nameof ( arg ) ) ; } }

XAML Dependency Property

public static DependencyProperty AddressProperty = DependencyProperty . Register ( nameof ( Address ) , typeof ( AddressType ) , typeof ( MainWindow ) ) ;

Logging

void Method ( int arg ) { Log ( nameof ( Method ) , "Method Logged" ) ; }

And much, much more...