# C# Language Design Meeting for April 9th, 2025

## Agenda

- [Dictionary expressions](#dictionary-expressions)
- [Collection expression arguments](#collection-expression-arguments)

## Quote of the Day

- "Because we test everything, to our credit and our horror"

## Discussion

### Dictionary expressions

Champion issue: https://github.com/dotnet/csharplang/issues/8887  
Specification: https://github.com/dotnet/csharplang/blob/9735444553fbfaacdff76e77ef6ef0c14f1fcccb/proposals/dictionary-expressions.md#concrete-type-for-ireadonlydictionaryk-v

First up today, we reviewed a question on what the default type for dictionary expressions targeted at `IDictionary` and `IReadOnlyDictionary` types. For this, we needed to
untangle our previous design work around collection expressions: in 2023, we'd
[decided to not guarantee `List<T>`](https://github.com/dotnet/csharplang/blob/9735444553fbfaacdff76e77ef6ef0c14f1fcccb/meetings/2023/LDM-2023-08-09.md#conclusion-1), but
this is not what was specified. This was due to some misunderstandings between the working group and the broader LDM; we wanted to start by understanding the principles the
working group used to decide on the current rule, and then apply that to dictionary expressions. There are two aspects:

1. For the readonly interfaces (namely, `IEnumerable<T>`), we wanted users to be able to rely on that readonly-ness. It was important to the group that it wouldn't be possible
   to downcast and mutate the collection.
2. For the mutable interfaces, it wasn't clear what the benefit of not guaranteeing `List<T>` would be. This is the BCL's flagship collection type, and the one that has the
   largest optimization effort throughout the BCL.

Given these reasons, we accept that as the new motivating set of rules for collection expressions, and we have a clear guideline of how to apply the same rules for dictionary
interfaces as well. For `IReadOnlyDictionary<TKey, TValue>`, the compiler should guarantee readonly-ness. It is free to use any implementation it so desires, so long as it's
a "conforming" implementation, much like the specification for collection expression talks about conforming implementations. The precise rules for conformance should be
brought to LDM for approval, but they need to ensure that the dictionary is truly readonly and cannot be mutated, even if viewed through an interface that may optionally
allow mutation (for example, returning `True` for `ICollection.IsReadOnly`, and throwing on `ICollection.Add`, if it does in fact implement `ICollection`). For the mutable
dictionary interfaces, we don't see a reason to not just guarantee `Dictionary<TKey, TValue>`; it is the flagship dictionary type of .NET, and the one that has the largest
optimization effort throughout the BCL. If this changes at some point in the future, we can look at it then.

#### Conclusion

We will guarantee `Dictionary<TKey, TValue>` for the mutable dictionary interfaces. We will allow the compiler to use any compliant BCL or synthesized type for the readonly
dictionary interfaces, where compliant means that it must ensure that the dictionary cannot be mutated by downcasting or alternate interface views.
We update the assumptions for collection expressions that constructing an `IList<T>` or `ICollection<T>` uses a `List<T>`.

### Collection expression arguments

Champion issue: https://github.com/dotnet/csharplang/issues/8887  
Specification: https://github.com/dotnet/csharplang/blob/9735444553fbfaacdff76e77ef6ef0c14f1fcccb/proposals/collection-expression-arguments.md#arguments-for-interface-types

We did not have enough time to do more than give an overview of this question today and hear some initial sentiment. However, the initial sentiment seemed positive for two
reasons:

1. For the mutable dictionary types, the first question today specified that `Dictionary<TKey, TValue>` is the concrete type used. Why would you not be able to use the
   constructors from that type then?
2. For the readonly dictionary types, the first question today specified that a "compliant" implementation must be used. Why couldn't we make "compliant" include a "must
   be able to be constructed with a comparer argument"?

Again, no conclusions here today, but we've primed the discussion for next week.
