There's lots you lose with IEnumerable<T>. Count and random access are the most obvious. LINQ sort of gives this back to you. The Count() method will give you the count, and is optimized to try and cast the IEnumerable<T> to an ICollection<T> in
order to get the count without having to iterate over the collection. However, I believe that is bad design. If the underlying collection is changed to no longer be an ICollection<T> the complexity of Count() has radically changed. Since the public interface
only exposed IEnumerable<T>, I have to expect that sort of behavior.

The ReadOnlyCollection types aren't ideal. I'd much prefer it if the collection designs had started with IReadOnlyCollection and ICollection had derived from there. IOW, I share your consternation about the existence of non-readonly methods that throw exceptions.
That said, however, we have what we have, and in practice there's seldom if ever an issue with the IsReadOnly/exception design of ReadOnlyCollection types.