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.
Section 8.3.2 of the .NET Framework Design Guidelines Second Edition:
DO use
ReadOnlyCollection<T>
, a subclass ofReadOnlyCollection<T>
, or in rare casesIEnumerable<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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With