10

The new read-only interfaces in .NET 4.5 such as IReadOnlyCollection<T> and IReadOnlyDictionary<TKey,TValue> are very useful, especially since they have been implemented on common BCL types such as Collection<T>, List<T> and Dictionary<TKey,TValue>.

However, HashSet<T> and SortedSet<T> haven't been upgraded to implement IReadOnlyCollection<T>, and I can't see the logic behind this decision since those classes match the interface without any modification or breaking change. Was it just overlooked by the BCL team, or is there something I'm missing here?

(This is especially annoying since there are no built-in ways to wrap a set inside a IReadOnlyCollection<T>. Indeed, ReadOnlyCollection<T> wraps IList<T> and not ICollection<T>. I know writing my own wrapper is trivial.)

Julien Lebosquain
  • 40,639
  • 8
  • 105
  • 117
  • possible duplicate of [Why HashSet does not implement IReadOnlyCollection?](http://stackoverflow.com/questions/11849861/why-hashsett-does-not-implement-ireadonlycollectiont) – Sergii Volchkov Aug 21 '15 at 09:32

2 Answers2

13

Update 2015: Fixed in .NET 4.6

Read-only interfaces are implemented on collection types HashSet, LinkedList, Queue, SortedDictionary, SortedList, SortedSet, and Stack. [944715]

https://dotnet2015.blob.core.windows.net/changes/dotnet46-changes.txt

Colonel Panic
  • 132,665
  • 89
  • 401
  • 465
5

The most likely reason the IReadOnlyXxx interfaces where added in 4.5 was because they were required to make .NET collections usable in WinRT projects (Store and Phone apps). Necessary to properly map the collection to WinRT's IVectorView<> and IMapView<> interfaces. This is done automagically by the language projection built into the CLR. With the clincher that WinRT doesn't have the equivalent of an ISet<> interface so there just wasn't any need to change HashSet<>.


Update: the asymmetry was resolved in .NET 4.5.1, no doubt thanks to plenty of customer feedback :), HashSet<> now also implements IReadOnlyCollection<>

Jeff B
  • 8,572
  • 17
  • 61
  • 140
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • 6
    I'm fully aware of the implications of using `IReadOnlyCollection` vs using immutable collections (good timing indeed, I did some tests with them yesterday!). I don't use them as an assurance for immutability but rather as a "guaranteed non-lazy `IEnumerable` with a count", which has its uses. If the caller casts them back to the implemented type, well, I consider this as safe as modifying a private member with reflection. Thanks for mentioning the WinRT types, it seems to be the main reason these interfaces were added. – Julien Lebosquain Jan 19 '13 at 15:18
  • 1
    You even do not try to answer a question. – hazzik Mar 19 '14 at 04:28
  • Well, pretty sure I did. Looks like Julien got it. The WinRT language projection deserves a book by itself, writing one in an SO post is not very practical. – Hans Passant Jun 10 '14 at 21:02