- "Do we need dragon warnings?"
#5354
https://github.com/dotnet/csharplang/blob/760e4a772a06723ea6ab3edabe14029623302ea2/proposals/collection-literals.md
Today, we took a look at the current proposal for collection literals. The proposal is looking very good overall, but there are some open questions around how it should behave in some scenarios.
First, when the target-type of a collection literal is an IEnumerable<>
of some kind, what type is emitted by the
compiler? As written today, it's always List<>
, but this has the potential to cause allocations when they aren't
needed. It would be great, for example, if IEnumerable<string> e = [];
could just be emitted as a call to
Enumerable.Empty<string>()
, avoiding the need for an allocation entirely. That can't happen today, though, as it's
specified to be List<T>
. This would also mean that we couldn't do optimizations for scenarios that pass a fixed list
of constants to an IEnumerable<>
function: the consumer could downcast to List<>
and add to it. We think that,
given that we are talking about IEnumerable<>
and not some more specific type, it should be fine to not guarantee
what underlying type we end up using; indeed, that's the entire point of taking an interface, rather than a concrete
type.
Next, we looked at KVPs turning the collection literal into a Dictionary<>
automatically. We have some immediate
concerns with this provision: the user could just as easily want a List<KVP<K, V>>
instead of Dictionary<K, V>
.
There are also concerning differences in behavior with how such a dictionary would be constructed: a Dictionary
would be union semantics, where duplicate later keys can overwrite earlier keys (or, if specified slightly differently,
it could throw instead of overwriting). A list would contain both duplicate keys, which is a large change in behavior
with very little to indicate that the behavior has changed. A bit more digging pulled up the important scenario that
this rule is trying to cover: [.. dict1, .. dict2]
should result in a dictionary union of these two input dictionaries,
or [.. dict1, key: value]
should result in a copied dictionary, with key
set to value
. We therefore brainstormed
an alternate rule, that would be useful not just for Dictionary<>
, but also for any collection being splatted into
another collection: the type of a splat should impact the natural type of a collection literal. This is a rough idea
that the working group will need to further explore, but at first glance it seems both powerful and like it addresses
the concerns that created this rule in the first place.
No conclusions were reached today, but the working group has more feedback to go iterate on and come back to LDM with.