C#: Wrapping collections vs Extension methods
Another interesting thing I've noticed in C# world is that there seems to be a trend towards using extension methods as much as possible. One area where this is particularly prevalent is when working with collections.
From reading Object Calisthenics and working with Nick I have got used to wrapping collections and defining methods on the wrapped class for interacting with the underlying collection.
For example, given that we have a collection of Foos that we need to use in our system we might wrap that in an object Foos.
public class Foos { private readonly IEnumerable<Foo> foos; public Foos(IEnumerable<Foo> foos) { this.foos = foos; } public Foo FindBy(string id) { return foos.Where(foo => foo.Id == id).First(); } // some other methods to apply on the collection }
Extension methods provide another way of achieving the same thing while not needing to wrap it.
public static class FooExtensions { public static Foo FindBy(this IEnumerable<Foo> foos, string id) { return foos.Where(foo => foo.Id == id).First(); } }
It seems like there isn't much difference in wrapping the collection compared to just using an extension method to achieve the same outcome.
The benefit I see in wrapping is that we take away the ability to do anything to the collection that we don't want to happen. You only have the public API of the wrapper to interact with.
The benefit of the extension method approach is that we don't need to create the object Foos – we can just call a method on the collection.
I'm not sure which is a better approach – certainly languages which provide the ability to open classes seem to favour taking that approach over wrapping but I still think it's nice to have the wrapper as it means you don't have to be explicitly passing collections all around the code.
But maybe that's just me.
Hi,
Another benefit of wrapping is you can implement an interface on the wrapper so that you can mock calls to the methods it exposes.
Daniel Cazzulino has a good article on the subject,
http://www.clariusconsulting.net/blogs/kzu/archive/2009/02/19/Makingextensionmethodsamenabletomocking.aspx
I think if you applied similar logic you would end up with code like
IEnumerable foos = new List();
foos.Finders().FindBy(id);
Regards,
Paul
PaulBlamire
24 Feb 09 at 12:49 am
oops, angle brackets for generic declaration and instantiation stripped, but you get the drift
Paul
PaulBlamire
24 Feb 09 at 12:50 am
[...] wrote previously about the differences between wrapping collections and just creating extension methods to make our use of collections in the code base more descriptive but I've noticed in code I've been [...]
Wrapping collections: Inheritance vs Composition at Mark Needham
24 Jul 09 at 1:10 am