-1

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?

Massimiliano Kraus
  • 3,638
  • 5
  • 27
  • 47
  • 4
    Unless one of the language designers answers this, any answers to this question will be primarily opinion-based... – Matthew Watson Oct 09 '17 at 09:24
  • 2
    Simply: `typeof` and `default` are working with type, while [`nameof`](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/nameof) works with more than that. The real question is here why **you think** `nameof` should work with types similarly to e.g. `typeof`. – Sinatr Oct 09 '17 at 09:26
  • @MatthewWatson, yes, probably you're right... do you think I should change the question into something like _"what are the pros and cons of prohibiting `nameof()` on synonymous?"_? Would it be less opinion-based? Or do you know how can we have the confirmation from some C# guy? :-) – Massimiliano Kraus Oct 09 '17 at 09:31
  • You can't really make this the kind of question to ask on StackOverflow, since it can't be objectively answered. – Matthew Watson Oct 09 '17 at 10:22

1 Answers1

4

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.

Massimiliano Kraus
  • 3,638
  • 5
  • 27
  • 47
  • But your argment about `the result is different from nameof(System.Object)` also applies to `typeof(object).FullName` ("System.Object") and `typeof(Object).FullName` (also "System.Object") and `typeof(System.Object).FullName` (again, "System.Object"). – Matthew Watson Oct 09 '17 at 09:27
  • @MatthewWatson I can't see how it applies also to `typeof().FullName`. `typeof()` is about a `Type`, not a "string representation", and the `Type` under `object` or `System.Object` is _exactly_ the same. Even further, the property is called `FullName`. The "`Full`" qualifier avoids any possible residual ambiguity. – Massimiliano Kraus Oct 09 '17 at 09:37