May 24, 2014 at 10:26 PM
Edited May 24, 2014 at 10:27 PM
C# Language Design Notes for May 21, 2014
Notes are archived
This is Part I. Part II is
- Limit the nameof feature? <keep current design>
- Extend params IEnumerable? <keep current design>
- String interpolation <design nailed down>
Limit the nameof feature?
The current design of the
feature allows for the named entity to reference entities that are not uniquely identified by the (potentially dotted) name given: methods overloaded on signature, and types overloaded on generic arity.
This was rather the point of the feature: since you are only interested in the name, why insist on binding uniquely to just one symbol? As long as there’s at least one entity with the given name, it seems fine to yield the name without error. This sidesteps
all the issues with the mythical
feature (that would take an entity and return reflective information for it) of coming up with language syntax to uniquely identify overloads. (Also there’s no need to worry about distinguishing generic
instantiations from uninstantiated generics, etc.: they all have the same name).
The design, however, does lead to some interesting challenges for the tooling experience:
public void M();
public void M(int i);
public void M(string s);
WriteLine(nameof(M)); // writes the string "M"
Which definition of
should “Go To Definition” on
go to? When does renaming an overload cause a rename inside of the
? Which of the overloads does the occurrence of
count as a reference to? Etc. The ambiguity is a neat trick at the language level, but a bit of a pain at the tooling level.
Should we limit the application of
to situations where it is unambiguous?
No. Let’s keep the current design. We can come up with reasonable answers for the tooling challenges. Hobbling the feature would hurt real scenarios.
Extend params IEnumerable?
By current design, params is extended to apply to
parameters. The feature still works by the call site generating a
with the arguments in it; but that array is of course available inside the method only as an
It has been suggested that we might as well make this feature work for other generic interfaces (or even all types) that arrays are implicitly reference convertible to, instead of just
It would certainly be straightforward to do, though there are quite a lot of such types. We could even infer an element type for the array from the passed-in arguments for the cases where the collection type does not have an element type of its own.
On the other hand, it is usually bad practice for collection-expecting public APIs to take anything more specific than
. That is especially true if the API is not intending to modify the collection, and no meaningful params method would do so: after all, if your purpose is to cause a side effect on a passed-in collection, why would you give
the caller the option not to pass one?
Params only really makes sense on
. If we were designing the language from scratch today we wouldn’t even have params on arrays, but only on
. So let’s keep the design as is.