Search code examples
c#nameoftype-synonyms

Why doesn't nameof work on synonymous?


From this question I learned that the nameof() operator, introduced in C# 6.0, does not work on synonymous. So you can write nameof(System.Object) but not nameof(object).

Now, there are 2 other similar operators, typeof() and default(), and they work perfectly on synonymous. You can write:

default(object);
default(int);
typeof(string);
typeof(long);

as well as:

default(Object);
default(Int32);
typeof(String);
typeof(Int64);

and the results are the same.

I guess that it would have been possible to build the nameof() operator to operate with synonymous too.

So the question is: WHY it was not implemented to work with object, string, int, etc.? Is my guess wrong (i.e. it's impossible to implement)? Or was it a design choice?


Solution

  • I think it's a design choice.

    typeof() operator returns a Type. Since object and System.Object express the same exact Type, there is no problem in writing typeof(object).

    The same applies to default(): it is null in both cases (or 0 or whatever).

    Now, for nameof(), the context is a bit harder.

    Pretend that nameof(object) is allowed. What should it return?

    1. "object". But now the result is different from nameof(System.Object), and it makes no sense, given that the class is the same.
    2. "Object" uppercase, the same as nameof(System.Object). But now we have a strange exception on the rule: nameof() returns the exact string representation of the expression passed as parameter... except object (and the other synonymous). This can cause subtle issues, for example I might give for sure that nameof(object) returns "object" since nameof(Table) returns "Table" and nameof(MyComponent.SomeProperty) returns "SomeProperty", and so on.

    Making nameof() not available on synonymous definitely resolved the ambiguity.