Difference between nameof and typeof

user1400995 picture user1400995 · Nov 11, 2015 · Viewed 10.1k times · Source

Correct me if I am wrong, but doing something like

var typeOfName = typeof(Foo).Name;

and

var nameOfName = nameof(Foo);

should give you exactly the same output. One of the understandable reasons according to this source: https://msdn.microsoft.com/en-us/library/dn986596.aspx is that

"Using nameof helps keep your code valid when renaming definitions"

If you want to get the class instance as string it is not possible to do something like that:

var fooInstance = new Foo();
var nameOfName = nameof(fooInstance);

however, you can do something like:

static string GetName<T>(T item) where T : class 
{
  return typeof(T).GetProperties()[0].Name;
}
var typeOfName2 = GetName(new { fooInstance });

In both cases (typeof and nameof) a refactoring is possible, so I dont see any other reason for reinventing another higher level keyword, such as nameof, to perform something that already exists. Are there any differences between them that I don't clearly see?

Finally, I would appreciate if could someone point me to a reference source to have a look at the implementation of nameof. Does it use Reflection?

Update 1: Taken from here

nameof is apparently as efficient as declaring a string variable. No reflection or whatsoever!

var firstname = "Gigi";
 var varname = nameof(firstname);
 Console.WriteLine(varname); // Prints "firstname" to the console

When you check out the MSIL generated you will see that it is equivalent to a string declaration because an object reference to a string gets pushed to the stack using the ldstr operator:

IL_0001: ldstr "Gigi"
IL_0006: stloc.0
IL_0007: ldstr "firstname"
IL_000c: stloc.1
IL_000d: ldloc.1
IL_000e: call void [mscorlib]System.Console::WriteLine(string)

Answer

Luaan picture Luaan · Nov 11, 2015

Two reasons:

nameof turns into a compile-time constant. typeof(...).Name requires a bit of reflection. It's not overly expensive, but it can hurt in some cases.

Second, it's used for other things than type names. For example, arguments:

void SomeMethod(int myArgument)
{
  Debug.WriteLine(nameof(myArgument));
}

You can also get the name of class members and even locals. Needless to say, this is quite useful for debugging information. It's also one of the ways to implement less fragile reflection when e.g. parsing expression trees (sadly, on the project where I'd use this, we're still stuck on .NET 4.0 with C# 5 - it'd save me a few hacks here and there).

And to clear up some confusion, nameof is not a function, and neither is typeof. It's a compile-time operator, and it's always evaluated at compile-time (though obviously, generics move the "compile-time" a bit further in time).