Exposing List<T> vs IList<T>

Unless you specifically want to expose a List<T> via a public interface (either as a return type or as a method argument), it’s a better idea to expose an IList<T>, ICollection<T>, or even an IEnumerable<T> depending on your needs. Recently I had to implement a generic list class that implemented property notifications and for this purpose I wrote a collection class that implemented IList<T> which by the way implements both ICollection<T> and IEnumerable<T>. I thought it’d be a simple matter to change members of certain types that used a List<T> to use this new collection class.

Unfortunately, I found that there were several methods in containing classes as well as calling classes that expected List<T> objects (even though the callers only used IList<T> or ICollection<T> members). Eventually I ended up having to change calling code and utility helper methods to use an IList<T> or ICollection<T> as appropriate. (Note that exposing the notification list was out of the question as it was not accessible to some of the callers and it is not good practice anyway).

In some cases the code used List<T> specific methods like Find, but if you have LINQ available then you don’t need to use the List<T> methods since you have alternate and usually more useful extension methods that you can use. I suppose I am over-specializing here by talking about List<T> in particular because it’s probably a good general practice to always expose the least derived class that you really need to.

Note that if you really need to expose a solid class without letting the users change the collection, then using ReadOnlyCollection<T> would be the correct approach compared to directly exposing the List<T> or Collection<T> object or their related interfaces like IList<T>.


4 thoughts on “Exposing List<T> vs IList<T>

  1. Good point. I typically manage list types internally using List and then only expose a readonly property of that list using the AsReadOnly() method, like so:

    public IList MyTypes
    get { return _myTypes.AsReadOnly(); }

    I find this to be the best approach for most of my projects and it prevents me from creating crap logic to manage the lists outside their scope. 🙂

    Good post!

  2. Even with LINQ available, it drives me nuts that you can’t call things like Find on the generic IList. In my current project, we just said “screw it” and made it standard to return List.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s