views:

509

answers:

5

I had another developer ask why I use List all over the place ... and I thought about it for a minute ... and couldn't come up with a definitive answer.

If you inherit from the collection base class to extend instead of using List(Of T) - what advantages do you get? Or - what don't you get with List?

+4  A: 

Generic List gives you performance boost.

See this question:

Do C# Generics Have a Perfomance Benefit?

Quote from MSDN:

It is to your advantage to use the type-specific implementation of the List<(Of <(T>)>) class instead of using the ArrayList class or writing a strongly typed wrapper collection yourself. The reason is your implementation must do what the .NET Framework does for you already, and the common language runtime can share Microsoft intermediate language code and metadata, which your implementation cannot.

aku
+1  A: 

List is not thread safe, and not meant to be exposed. You can use a Collection(Of T) instead (note that this is different from CollectionBase), or simply expose IList(Of T) or IEnumerable(Of T).

Jon B
A: 

Inheriting from Collection(Of T) is recommended by Microsoft. The List(Of T) API is not guaranteed to remain the same from version to version. So, if you use List(Of T) in your public interfaces, your code may break when running on new versions of the CLR.

Krzysztof Cwalina, one of the designers of the BCL, has this to say about List<T>:

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>.

Source

ageektrapped
Can you provide a link to this MS recommendation? I doubt that any of base classes can be changed in future versions of FW.
aku
Also CLR doesn't affect BCL, so how can it affect List<T> ?
aku
MS has a history of going out of it's way to maintain compatibility between versions. I have to think a breaking change to List(Of T) is highly unlikely.
ScottS
Thanks for the reference. It seems like reasonable advice, but it doesn't suggest that a future version of .Net will break your code if you use List(Of T).
ScottS
+1  A: 

A generic List<> has been designed for speed and internal use. The generic Collection<> on the other hand, has been designed for extensibility.

One of the advantages of the Collection<> class is that you can override a few different methods (ClearItems(), InsertItem(), RemoveItem() and SetItem()). The generic List<> type, on the other hand, provides no methods that can be overriden.

Why does this matter? Say, for example, that future requirements mandate that you raise an ItemAdded event when an item is added to the collection. Had you used the List<> type, you don't have too many options. Had you used the Collection<> class, however, you have the ability to expose a new ItemAdded event and override the InsertItem() method so that it raises the ItemAdded event when an item is added.

senfo
+1  A: 

Type casting costs time, and is prevented when you are using generics. If you use List(Of T) there is no type casting needed, because it will be a strong-typed collection. If you use ArrayList you are casting from Object to your own type and vice versa, which causes extra overhead.

Besides that, you prevent type casting problems that you cannot detect at compile time. (For example, adding a int in a array list that should contain strings is not a problem when you use an array list, but can cause a invalidcastexception when you do not expect an int at run time. Using generic lists or collections prevents this because the code will not compile.)

Hope this helps.

Jeroen Landheer