Follow @RoyOsherove on Twitter

Understanding the different generic collections in .NET (List<T>, BindingList<T>, Collection<T>)

An innocent question came up in one fo the mailing lists I subscribe to. It was about when would you want to derive from the various generic collections in the framework. That also prompted another discussion about the various kinds of generic collections in .NET you shoudl be aware of, which I think most people can't really tell the difference between when and where to use which of them. So here are parts of that discussion, quoted.
First, some reasons you'd want to derive from a generic collection .NET:
"Custom sorting,
Validation,
Factory methods,
AddRange capabilities,
Custom serialisation,
Event hooking/raising
Delayed fetching (caching)"
and adds some more about the various collections:
"Well what I tell folks is they need to know 3 "lists".
  • List(Of)  : List<T>
  • Collection(Of) :  Collection<T>
  • and BindingList(Of).  : BindingList<T>
I tell them to use: -
  • List(Of) anywhere they use to use ArrayList, or anywhere they are ReDim'ing an array. But not to expose this outside of a class generally as it exposes a lot of methods that can change the internal data (e.g Sort)
  • BindingList(Of) If they are using the collection for binding in Windows.Forms (or ASP.NET) then they should use BindingList. But they will often need to inherit from it, and override some methods (e.g sorting)
  • Collection(Of). When not using binding, and you want to control what methods are exposed, and or intercept when objects are added or removed, you should derive from Collection(Of)
Of course there's others they need to know such as Dictionary and ReadOnlyCollection. "
And Rocky Lhotka adds to that discussion:
"In CSLA .NET I created my own generic collection classes because I needed to extend the behaviors of IBindingList(Of T) in various ways. The additional requirements include:
* Persistence (some objects know about databases)
* Sorting
* Filtering
Those last two are interesting (I think), because I was able to create SortedBindingList and now FilteredBindingList, which are "updatable views"
against any List(Of T) that add sorting or filtering respectively.
Dim list As New List(Of String)
' add items to list
Dim sorted As New Csla.SortedBindingList(Of String)(list)
sorted.ApplySort()
' enumerate through the sorted list
For Each item As String in sorted
  Debug.WriteLine(item)
Next
The result is sorted output of the list. Because it is generic, the sorted list works against any IList(Of T), including lists of simple or complex types (like CSLA .NET business objects). Even better, any changes you make to 'sorted' are automatically reflected in 'list' and visa versa. That's because SortedBindingList isn't a copy, it is a view into the actual underlying list object.
You could envision similar constructs based around tree structures - I'd love to build a Red-Black Binary Tree along the lines of SortedBindingList to provide a balanced binary tree "view" of data in a list.
Also, I've been unable to determine for sure whether Queue(Of T) uses efficient multi-threaded reader-writer locking, but I don't think it does.
For some applications, having separate thread locking on the head and tail of the queue becomes important, but I think Queue(Of T) just uses a simplistic write lock scheme on the whole queue... That's harder to get right, but would be another reason to create your own generic collections."

Could JaJah be the next Skype Killer? Almost

Does your desktop look cool/geeky these days? You could win some prizes.