9

In C# 6.0 you can write this:

var instance = default(object);
var type = typeof(object);

They have the same result of:

var instance = default(System.Object);
var type = typeof(System.Object);

But you can't write this:

var name = nameof(object);

It generates the following error:

Invalid expression term 'object'.

But you can still write this:

var name = nameof(System.Object);

Why nameof(object) does not compile?

Massimiliano Kraus
  • 3,638
  • 5
  • 27
  • 47
  • 2
    Try: `nameof(Object)` instead. `nameof()` doesn't work on synonyms, only on the original classnames. – Jeroen van Langen Nov 04 '16 at 11:51
  • @CodeCaster, to get the class `Object`'s name as string – Jeroen van Langen Nov 04 '16 at 11:52
  • 1
    @CodeCaster Jeroen is right. Try it if you don't believe it. –  Nov 04 '16 at 11:53
  • 1
    @CodeCaster also on classnames. I use it for logging purposes. Whenever I rename a class, this will be changed to.. Same applies to `nameof(int)` vs `nameof(Int32)` – Jeroen van Langen Nov 04 '16 at 11:53
  • 1
    Not sure why this was closed. It's a perfectly valid question, if not a bit short. If anything, it goes against the common idea that `Object` and `object` are entirely interchangeable. See [here](http://stackoverflow.com/questions/1017282/c-difference-between-system-object-and-object). This question shows that in fact, they are *not* the same. – Rob Nov 04 '16 at 11:56
  • @Jeroen alright, TIL. – CodeCaster Nov 04 '16 at 11:57
  • @Rob agree there. The difference is that `object` is a synonym for `Object` and `nameof()` doesn't work on synonyms. – Jeroen van Langen Nov 04 '16 at 11:57
  • 3
    `object` is a *keyword* in the C# language. Keywords are rather a big deal to compilers, they disambiguate syntax and help generate good error messages. But with the hang-up that keywords are not identifiers so nameof() can't work. – Hans Passant Nov 04 '16 at 12:04
  • @HansPassant how can keywords "help generate good error messages?" – Massimiliano Kraus Nov 04 '16 at 12:13
  • 3
    Keywords are the rock-solid foundations upon which a language is built. The parts of a statement that have a completely unambiguous meaning and the parser can rely on to mean only one thing. If a parser can't rely on such guarantees then it has to guess what the programmer intended. Guesses never produce good error messages, it might guess wrong and send the programmer into a rabbit hole. It would technically not be impossible for the compiler to still recognize `object` in the specific case of parsing the nameof operand. It would however greatly uglify the expression parser. – Hans Passant Nov 04 '16 at 12:19
  • 2
    @Hans you mean like ideone (Mono)'s _"CS1525: Unexpected symbol `)`, expecting `.`"_ after `nameof(object)`? :) – CodeCaster Nov 04 '16 at 12:21
  • 2
    Yes, good example :) Mono treats it like an identifier instead of a keyword, tsk, tsk. – Hans Passant Nov 04 '16 at 12:29
  • _"It would however greatly uglify the expression parser"_ @HansPassant are you saying that adding the recognition of keywords in the `nameof()` statement would have slowed down the parsing of the code? I'm not expert of low-level stuffs like compiler parsing, so it's a honest question. – Massimiliano Kraus Nov 04 '16 at 13:40
  • 1
    Speed is not an issue. The expression parser would have to accept keywords like `object`, `string`, `int`, etc. But only in the specific case of it being used to parse the nameof operand. And still deal with the wonky cases like `object int` and produce a decent error message for them. The expression parser is one of the most difficult parts of a compiler, there is lots of expressive power in a language like C#. The less special cases, the lower the risk that it accidentally accepts malformed code or spits out a bad diagnostic. – Hans Passant Nov 04 '16 at 13:49

1 Answers1

14

The difference is that object is a synonym for the class Object and nameof() doesn't work on synonyms.

Same applies to nameof(int) vs nameof(Int32)

Jeroen van Langen
  • 21,446
  • 3
  • 42
  • 57
  • 3
    Relevant documentation: https://msdn.microsoft.com/en-au/library/dn986596.aspx "The following are worth mentioning that produce errors: *predefined types (for example, int or void)*" – Rob Nov 04 '16 at 12:01
  • @Rob well that's the reference, not the specification. Technically, `System.Object` is a predefined simple type, and `object` its alias, so neither should work according to that description... – CodeCaster Nov 04 '16 at 12:25