Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 958
Mark Levison Avatar asked May 28 '09 15:05

Mark Levison


2 Answers

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.

like image 177
Jeff Moser Avatar answered Nov 07 '22 09:11

Jeff Moser


First off, ReadOnlyCollection<T> does implement IEnumerable<T> and IList<T>. With all of the extension methods in .NET 3.5 and LINQ, you have access to nearly all of the functionality from the original List<T> class in terms of querying, which is all you should do with a ReadOnlyCollection<T> anyways.

That being said, your initial question leads me to make some suggestions...

Returning List<T> is bad design, so it shouldn't be a point of comparison. List<T> should be used for implementation, but for the interface, IList<T> should be returned. The Framework Design Guidelines specifically state:

"DO NOT use ArrayList or List<T> in public APIs." (Page 251)

If you take that into consideration, there is absolutely no disadvantage to ReadOnlyCollection<T> when compared to List<T>. Both of these classes implement IEnumerable<T> and IList<T>, which are the interfaces that should be returned anyways.

like image 36
Reed Copsey Avatar answered Nov 07 '22 10:11

Reed Copsey