ReadOnlySet<T> in .NET 9

6/26/2024
2 minute read

The next preview (preview 6) will bring a new type ReadOnlySet<T>. This is a read-only set that is similar to ReadOnlyCollection<T>. Let's see how it works and why it was introduced.

So what does that new try to solve? Well, there are two issues with the "current" approach. Current as in .NET 8

1. IReadOnlySet isn't enough

For sure, we already have the IReadOnlySet<T> interface. So why isn't that enough? Let's have a look at List<T> and IReadOnlyList<T>, which suffers somewhat from the same issue.

var list = new List<int> { 1, 2, 3 };
IReadOnlyList<int> readOnlyList = list;

// You can easily cast it back to a List<T> and modify it
var list2 = (List<int>)readOnlyList;
list2.Add(4);

Of course, consumers of your API shouldn't do that, but you can't prevent it. The same applies to IReadOnlySet<T>. So that is why we have a AsReadOnly on List:

var list = new List<int> { 1, 2, 3 };
var readOnlyList = list.AsReadOnly();

// You can't cast it back to a List<T>
var list2 = (List<int>)readOnlyList; // Exception

That is exactly what ReadOnlySet<T> will do for IReadOnlySet<T>:

var set = new HashSet<int> { 1, 2, 3 };
var readonlySet = new ReadOnlySet<int>(set);

2. Wrong workaround

If users tried to roll out their own way of creating a read-only set, they would have to do something like ImmutableHashSet<T> or FrozenSet.

var set = new HashSet<int> { 1, 2, 3 };
var readOnly = set.ToFrozenSet(); // Or ToImmutableHashSet()

While technically this is working, it has two major problems:

  1. Immutable collections like ImmutableHashSet<T> or FrozenSet need to copy the whole collection into its own memory to guarantee immutability. This can be a waste of memory and CPU cycles.
  2. It's not really readonly. Readonly and immutable are two different concepts. Readonly means you can't modify it, but you can still modify the original collection, which then would be reflected in the "readonly" collection. With immutable collections, this wouldn't be reflected. I even have a whole blog post about it: "ReadOnlyCollection is not an immutable collection".

And that is why we have ReadOnlySet<T> now. If you want to dive deeper, check out the API Propsal: https://github.com/dotnet/runtime/issues/100113

Three new LINQ methods in .NET 9

Even though we are in the alpha of .NET 9 and .NET 8 was released not more than two months ago, the dotnet team does not sleep and pushes new changes! In this blog post, we are checking what new methods were added to everyones favorite: LINQ.

A new lock type in .NET 9

There is a new sheriff in town when it comes to the lock keyword, And that is the new System.Threading.Lock type that is introduced in .NET 9. And yes, I know - we still need time to digest the big .NET 8 release.

MemoryCache, DistributedCache and HybridCache

The latest preview (.NET 9 preview 4) brought another caching structure to the .NET world - so let's order some things here.

An error has occurred. This application may no longer respond until reloaded. Reload x