Why doesn’t generic ICollection implement IReadOnlyCollection in .NET 4.5?

There are probably several reasons. Here are some:

  • Huge backwards compatibility problems

    How would you write the definition of ICollection<T>? This looks natural:

    interface ICollection<T> : IReadOnlyCollection<T>
    {
        int Count { get; }
    }
    

    But it has a problem, because IReadOnlyCollection<T> also declares a Count property (the compiler will issue a warning here). Apart from the warning, leaving it as-is (which is equivalent to writing new int Count) allows implementors to have different implementations for the two Count properties by implementing at least one explicitly. This might be “amusing” if the two implementations decided to return different values. Allowing people to shoot themselves in the foot is rather not C#’s style.

    OK, so what about:

    interface ICollection<T> : IReadOnlyCollection<T>
    {
        // Count is "inherited" from IReadOnlyCollection<T>
    }
    

    Well, this breaks all existing code that decided to implement Count explicitly:

    class UnluckyClass : ICollection<Foo>
    {
         int ICollection<Foo>.Count { ... } // compiler error!
    }
    

    Therefore it seems to me that there’s no good solution to this problem: either you break existing code, or you force an error-prone implementation on everyone. So the only winning move is not to play.

Leave a Comment