Description
Description
Several of the generic collection interfaces were updated to implement their readonly counterparts using default interface members.
Version
.NET 10 Preview 6
Previous behavior
The generic collection interfaces did not provide the readonly collection interfaces as part of their inheritance hierarchy
New behavior
The generic collection interfaces now provide the readonly collection interfaces as part of their inheritance hierarchy
Type of breaking change
- Binary incompatible: Existing binaries might encounter a breaking change in behavior, such as failure to load or execute, and if so, require recompilation.
- Source incompatible: When recompiled using the new SDK or component or to target the new runtime, existing source code might require source changes to compile successfully.
- Behavioral change: Existing binaries might behave differently at run time.
Reason for change
The generic collection interfaces were introduced in .NET Framework 2.0, while their readonly variants were introduced in .NET Framework 4.0. Since being introduced, the .NET team has received innumerable requests to consolidate the inheritance hierarchies to simplify the overall developer experience.
When default interface members were introduced, this presented an opportunity for this to happen in a generally binary compatible fashion. After analysis of the ecosystem and reaching a high bar of confidence that the risk of breaking existing code would be minimal, it was decided to take the change.
Recommended action
In rare circumstances this can introduce a "diamond-problem" where the runtime cannot resolve the API that is intended to be invoked. This can occur as a source breaking change for developers recompiling their applications or as a binary breaking change if they are utilizing "roll forward".
Such a diamond problem could be observed if a developer had defined their own interface that implemented one of these readonly interfaces and which provided a default implementation for the members. A derived type then implemented that interface as well as one of the non-readonly generic collection interfaces. The fix for such a diamond is to ensure you explicitly implement the relevant members on the type that derives both, allowing the ambiguity to be resolved.
C++/CLI users trying out initial previews of .NET 10 may need to manually apply a workaround to get source compiling.
They will encounter a warning similar to the following:
C2668 'IReadOnlyCollection::Count::get': ambiguous call to overloaded function
This will be surfaced on a piece of code similar to:
return collection->Count;
The workaround is to change this to insert a static cast to the target collection type:
return static_cast<IReadOnlyCollection^>(collection)->Count;
This workaround will not be required when .NET 10 is officially released.
Feature area
Core .NET libraries
Affected APIs
The following interfaces are impacted:
ICollection<T>
implementsIReadOnlyCollection<T>
IDictionary<TKey, TValue>
implementsIReadOnlyDictionary<TKey, TValue>
IList<T>
implementsIReadOnlyList<T>
ISet<T>
implementsIReadOnlySet<T>
Metadata
Metadata
Assignees
Type
Projects
Status