Something "sort" of handy… [IListExtensions adds easy sorting to .NET list types – enabling faster search and removal, too!]


This blog has moved to a new location and comments have been disabled.

All old posts, new posts, and comments can be found on The blog of dlaa.me.

See you there!

Comments (4)
  1. Rainer Prem says:

    I wouldn't subscribe to "T this[int index] { get; set; } // Good as-is" because using the setter will mostly ruin the sort order, too.

    Also you will get no information when the sort key of an item is changed.

  2. Delay says:

    Rainer.Prem,

    Great point, thank you! For some reason, every time I thought about the [] indexer, I only thought about the getter (which it seems we agree is safe as-is). I completely with you that the setter is just as dangerous as the Insert method and should probably be avoided similarly (as I discuss above).

    Regarding your comment about the sort key of an item changing, my underlying assumption (which I should have explicitly stated!) was that the items themselves were stable with regard to sort order (i.e., they wouldn't change order without being removed and added back to the list). I agree that if that's not the case, then the sorting can get messed up – but I believe the same would be true if something like List(T).Sort or even SortedList were used unless some mechanism were put in place to find out that an item changed its sort key.

    Thank you for reading and for the great feedback! 🙂

  3. Philip the Duck says:

    You say "Subclassing would be the obvious "solution" to this problem, but it's not a good option here because the original methods aren't virtual on ObservableCollection(T)…".

    However all 'collection modifier' methods of ObservableCollection<T> *do* internally call the corresponding *protected virtual* methods ClearItems(), InsertItem(), RemoveItem() and SetItem(), so you can subclass and override those virtual methods and capture Add(), Insert(), etc. calls without having to change all your existing existing code to use the *Sort() extension methods instead.

    [This is not relying on an internal implementation of ObservableCollection<T>, but is actual documented functionality – see

    msdn.microsoft.com/…/ms654928(v=VS.95).aspx ]

  4. Delay says:

    Philip the Duck,

    Fine points, thank you for raising them! 🙂

    I considered that approach as well, but there are some issues with it. One is something I mention in my post – that subclassing limits the scope of such changes to *just* the subclassed class and prevents them from being more generally useful like the IList-based extension methods I came up with are. I suspect everyone will prioritize this tradeoff differently, but it's something to keep in mind.

    But a bigger problem is hinted at by the "Remarks" section of the documentation page you link to: "This implementation raises the CollectionChanged event.". Specifically, if you override InsertItem, then you have to decide whether or not to call the base class implementation of that method. The default answer is "Of course – that's the rule of subclassing – if you don't, then all kinds of things might break!". Except that in this case, you *can't* call the base class method because it will actually perform the insert and it probably won't use right index to keep the list sorted. So you'll have to skip calling the base implementation and that means you'll have to try to duplicate its functionality in your own code. This is tricky territory; Reflector shows that InsertItem does 4 other things right now and you'll need to duplicate them all or risk introducing bugs…

    But the bigger issue with this is that overriding InsertItem may force you to lie. By the point you get there, someone (maybe the user, maybe the collection itself) has already decided what index to insert at and it may be necessary to block the operation if it's not the right sorted location for that item. Or alternatively you might decide to insert it at the correct index and pretend you inserted it at the requested index. Either way, it feels wrong to me… 😐

    Maybe I'm still overlooking something (it would hardly be the first time!), but this doesn't seem like the right place to introduce sorting because of the kinds of issues it creates. So please let me know if there's a good solution that I'm missing here.

    And thanks again for your comments!

Comments are closed.