Why we don’t recommend using List<T> in public APIs

We don’t recommend using List<T> in public APIs for two reasons.

  • List<T> is not designed to be extended. i.e. you cannot override any members. This for example means that an object returning List<T> from a property won’t be able to get notified when the collection is modified. Collection<T> lets you overrides SetItem protected member to get “notified” when a new items is added or an existing item is changed.
  • List<T> has lots of members that are not relevant in many scenarios. We say that List<T> is too “busy” for public object models. Imagine ListView.Items property returning List<T> with all its richness. Now, look at the actual ListView.Items return type; it’s way simpler and similar to Collection<T> or ReadOnlyCollection<T>.

 

Published 26 September 05 12:35 by kcwalina

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# Rob P said on September 26, 2005 12:43 PM:
List<T> has so much useful stuff on it though :) Stuff, I might add, that is probably implemented using only members from IList (Find, FindAll, etc).

I guess we can wait for c# 3 and just extend IList<T> to have all the methods of List<T> we want.
# Kristoffer Henriksson said on September 26, 2005 12:54 PM:
Is there a replacement generic type that you recommend using instead?
# kcwalina said on September 26, 2005 4:23 PM:
We recommend using Collection<T>, ReadOnlyCollection<T>, or KeyedCollection<TKey,TItem> for outputs and properties and interfaces IEnumerable<T>, ICollection<T>, IList<T> for inputs.

If you need the List<T> useful APIs on your public API, just inherit from Collection<T> and add these APIs.
# bowerm said on September 29, 2005 12:11 PM:
Interesting. So you could say Collection<T> is the Generic equivalent of CollectionBase from v1.1?
# kcwalina said on September 30, 2005 12:53 AM:
Yes, Collection<T> is just a better CollectionBase. See http://blogs.msdn.com/kcwalina/archive/2005/09/23/Collections.aspx for more details.
# Michael Primeaux said on April 26, 2006 4:42 PM:

What is the recommended pattern for implementing a synchronized class that inherits from Collection<T>?  For example, I want to implement a SyncRoot property of type ReaderWriterLock. I do see where I can override (protected) the methods InsertItem, RemoveItem, ClearItems, and SetItem. However, I do not see an override for GetItem.
# Visual Studio Managed Code Analysis (FxCop) said on April 27, 2006 5:43 PM:
DoNotExposeGenericLists fires when I publicly expose a List&amp;lt;T&amp;gt; via a field, method, property, or...
# Roger said on September 6, 2006 9:15 AM:
<<We recommend using Collection<T>, ReadOnlyCollection<T>, or KeyedCollection<TKey,TItem> for outputs and properties and interfaces IEnumerable<T>, ICollection<T>, IList<T> for inputs. >>

Lets say I have my own collection of Persons deriving from collection<t> where I've added some new functionality... Do you mean that I should return a collection<t> instead of my derived collection type in a method returning Persons? Why? Harder for the clients to get hold of my collection specific API. Or do I misunderstand you?
# Perry Rapp said on September 12, 2006 2:29 PM:
Let me ask again a great question above (Michael's), which was apparently never answered:


What is the recommended pattern for implementing a synchronized class that inherits from Collection<T>?
# StrangeLog - Il blog di Andrea Saltarello said on September 14, 2006 9:20 AM:
# StrangeLog - Il blog di Andrea Saltarello said on September 14, 2006 9:21 AM:
Forse ha ragione David: la mia risposta al post di Giulio (per quanto sintetica e quindi non esaustiva) non
# StrangeLog - Il blog di Andrea Saltarello said on September 14, 2006 9:24 AM:
# kcwalina said on September 14, 2006 3:11 PM:
Michael and Perry, I will try to write some detailed guidelines on synchronization and post them to this blog. Unfortunatelly I am swampped right now and this is a relativelly large project. But quickly, in most scenarios, we recommend you wrap all collections and other components that need to be synchronized. In some other scenarios where the only resource that needs to be synchronized is the collection, I would simply inherit and add a sync root, optionally override the for protected members that modify Collection<T> and synchronize there.
# Visual Studio Managed Code Analysis (FxCop) said on October 12, 2006 12:51 PM:

DoNotExposeGenericLists fires when I publicly expose List&lt;T&gt; via a field, method, property, or

# Andreas said on October 17, 2006 12:40 PM:

What would you recommend in this scenario:

We have a class with an abstract method that is intended to be subclassed by the user of our framework. The method to override should produce a list of items that are determined in an application specific way.

Is it ok for this method to look like this:

   protected abstract IEnumerable<Item> GetItems(...);

> We recommend using ... IEnumerable<T>, ... for inputs.

I would argue that the output from this overridden method is the input to our API, and as such IEnumerable has the least requirements for the implementation.

How about users that use other languages than C#and VB? As far as I know, generics are CLS compliant. Can everybody override such a method?

# An Phu said on May 15, 2007 5:22 PM:

What are your recommendations in a webservice context?

# Haugerns Development Escapades » Blog Archive » .Net Collection<T> vs. List<T> said on December 2, 2007 4:21 PM:

PingBack from http://www.haugern.net/blog/net-collectiont-vs-listt/

# Vladimir Kelman said on April 1, 2008 12:51 PM:

Hi Krzysztof! Sorry for putting it here, but don't you think that there is a small bug in http://blogs.msdn.com/fxcop/archive/2006/04/27/585476.aspx example they put to explain your post? (Comments not allowed there). In class Person they have

private AddressCollection _Addresses = new AddressCollection();

But class AddressCollection does not have such parameterless constructor. The only one available takes Person owner parameter:

public AddressCollection(Person owner)

# Elegant Code &raquo; Replace your Collections with IEnumerable&lt;T&gt; said on April 7, 2008 4:16 PM:

PingBack from http://elegantcode.com/2008/04/07/replace-your-collections-with-ienumerablet/

# kcwalina said on April 7, 2008 8:20 PM:

Vladimir,

thanks for pointing it out. I will email the fxcop team about it.

# The Missing .NET #2: Collection&lt;T&gt; AddRange() | Jason Kemp .ca said on April 9, 2008 12:03 PM:

PingBack from http://www.ageektrapped.com/blog/the-missing-net-2-collectiont-addrange/

# &nbsp; Public APIlerde List&nbsp;by&nbsp;eser.ozvataf.com said on September 25, 2008 2:46 PM:

PingBack from http://eser.ozvataf.com/blog/29

# Frage zum string [] | hilpers said on January 17, 2009 12:45 PM:

PingBack from http://www.hilpers.com/1205717-frage-zum-string

# Supporto per estrapolare dati | hilpers said on January 17, 2009 3:53 PM:

PingBack from http://www.hilpers.it/2657139-supporto-per-estrapolare-dati

# Colllection-Klasse casten | hilpers said on January 18, 2009 5:41 AM:

PingBack from http://www.hilpers.com/1174313-colllection-klasse-casten

# ArrayList oder String.Concat() ? | hilpers said on January 20, 2009 10:37 AM:

PingBack from http://www.hilpers.com/269060-arraylist-oder-string-concat

# Lista de Generics con Eventos | hilpers said on January 20, 2009 2:06 PM:

PingBack from http://www.hilpers-esp.com/443042-lista-de-generics-con-eventos

# Phani said on March 9, 2009 1:09 PM:

What is the general recommendation for using List in WCF Operations?

Leave a Comment

(required) 
(optional)
(required) 

  
Enter Code Here: Required
Page view tracker