Why do ListBox.ObjectCollection and ListView.ListViewItemCollection have AddRange but not InsertRange or RemoveRange?
Question
So, both ListBox.ObjectCollection
and ListView.ListViewItemCollection
implement the IList
class, which provides Add
and Remove
methods but no AddRange
, InsertRange
, or RemoveRange
. However, ListBox.ObjectCollection
and ListView.ListViewItemCollection
also provide an AddRange
method -- just no InsertRange
or RemoveRange
.
Look at the ArrayList
class, on the other hand, which on top of implementing IList
also provides AddRange
, InsertRange
, and RemoveRange
. The same difference exists between the generic forms of this class and interface, List<T>
(which has AddRange
, InsertRange
, and RemoveRange
) and IList<T>
(which only provides Add
and Remove
).
I can understand the IList
and IList<T>
interfaces not providing AddRange
, etc. -- it's just an interface; anything beyond the minimum requirements of Add
, Remove
, RemoveAt
, etc. is optional. But, given the usefulness of the *Range
methods for the ArrayList
and List<T>
classes, and considering how handy they'd be for ListBox
and ListView
controls, I wonder why they don't exist for these controls.
Does anyone know? Is there something about the internal implementation of InsertRange
and RemoveRange
that makes these methods somehow less efficient, more complicated, or otherwise less appropriate for ListBox.ObjectCollection
and ListView.ListViewItemCollection
than AddRange
?
To be clear: I'm not looking for speculation of the "Looks like someone at Microsoft got lazy" variety; rather, I'm wondering if anyone actually knows of a legitimate difference between AddRange
and InsertRange
/RemoveRange
that might explain the absence of these latter methods from ListBox.ObjectCollection
and ListView.ListViewItemCollection
.
Solution
In general it's a pretty uncommon scenario to use InsertRange and (even more so) RemoveRange. Should RemoveRange, for example, remove the given range only if there is a continious range of elements similar to the given range, or should it remove the given elements one by one?
These methods are usually easy to implement if you need them. With the help of the extension methods you can have them to look almost like the native methods.
There are no signs in the code, showing that it would be complicated to implement those methods (just as thousands of other "useful" methods). Actually, the
ListView
implementation ofInsertItems
even takes an array of items already under the hood. Just the standardListViewItemCollection.Insert()
always provides array with 1 element. Take a look with the Reflector to theListViewNativeItemCollection.Insert()
:public ListViewItem Insert(int index, ListViewItem item) { //Various checks excluded .... this.owner.InsertItems(index, new ListViewItem[] { item }, true); //More code excluded ..... return item; }
I guess it just wasn't that important to implement that feature... so they didn't.
As Eric Lippert likes to say: "because no one ever designed, specified, implemented, tested, documented and shipped that feature".