Backwards Dave

This was an attempt to resume a very complex set of considerations. I agree that it may sound like the opposite.

Imagine that we have a function that returns a collection of items. This collection is internally created as an instance of List<T>. If we want this output to be writeable, the function can return List<T>, IList<T>, IList orICollection<T>. If we want it to be read/only, the function can return IReadOnlyList<T>, IReadOnlyCollection<T>, ICollection, IEnumerable<T> or IEnumerable.

What I mean is that, given the restriction of being writeable or read-only, the interface with more functionalities should be returned. Ultimately the type itself. The functionalities are implemented anyway by the type and these don’t compromise the intent.

By returning IReadOnlyList<T> , the client is free to enumerate the collection using for or foreach, and can also use the Count property. If IEnumerable<T> was returned instead, only foreach could be used and the collection has to be fully enumerated to get the number of items. for is also much more performant than foreach.

The is operator can be used to find if the collection implements these functionalities. This is done in several of the System.Linq operations. I don’t like this approach because, it’s performed at runtime, taking a hit on performance, and the intent is not explicit. I wrote an article on this subject:

There may be an exception to these rules. When the function is private or internal, the type should be explicitly returned. Not an interface. This way, the performance of enumeration is much better as the enumerator is not boxed. This is not relevant for types that implement IReadOnlyList<T> because the indexer can be used, but it’s very relevant for other collections.

I developed a Roslyn analyzer that can help you automatically find some of these patterns in your projects:

The answer is long but I hope it does explain my sentence. Feedback is welcome…



Principal Engineer @ Farfetch - R&D

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store