Search code examples
c#collectionsreadonly-collection

Why doesn't ReadOnlyCollection<> include methods like FindAll(), FindFirst(),


Following the suggestions of FxCop and my personal inclination I've been encouraging the team I'm coaching to use ReadOnlyCollections as much possible. If only so that recipients of the lists can't modify their content. In their theory this is bread & butter. The problem is that the List<> interface is much richer exposing all sorts of useful methods. Why did they make that choice?

Do you just give up and return writable collections? Do you return readonly collections and then wrap them in the writable variety? Ahhhhh.


Update: Thanks I'm familiar with the Framework Design Guideline and thats why the team is using FxCop to enforce it. However this team is living with VS 2005 (I know, I know) and so telling them that LINQ/Extension methods would solve their problems just makes them sad.

They've learned that List.FindAll() and .FindFirst() provide greater clarity than writing a foreach loop. Now I'm pushing them to use ReadOnlyCollections they lose that clarity.

Maybe there is a deeper design problem that I'm not spotting.

-- Sorry the original post should have mentioned the VS2005 restriction. I've lived with for so long that I just don't notice.


Solution

  • Section 8.3.2 of the .NET Framework Design Guidelines Second Edition:

    DO use ReadOnlyCollection<T>, a subclass of ReadOnlyCollection<T>, or in rare cases IEnumerable<T> for properties or return values representing read-only collections.

    We go with ReadOnlyCollections to express our intent of the collection returned.

    The List<T> methods you speak of were added in .NET 2.0 for convenience. In C# 3.0 / .NET 3.5, you can get all those methods back on ReadOnlyCollection<T> (or any IEnumerable<T>) using extension methods (and use LINQ operators as well), so I don't think there's any motivation for adding them natively to other types. The fact that they exist at all on List is just a historical note due to the presence of extension methods being available now but weren't in 2.0.