Sorting a ReadOnlyListBase collection of objects In-Place : possible?

Sorting a ReadOnlyListBase collection of objects In-Place : possible?

Old forum URL: forums.lhotka.net/forums/t/5301.aspx


awbacker posted on Tuesday, August 26, 2008

I am trying to sort a list of child objects in-place, but can't figure out how. 

I have a regular root object, and a ReadOnlyListBase() collection of ReadOnlyBase objects as a child.  I am trying to sort this in the FetchPost event of the Root object.

When I want to sort, I am using the ArrayList.Adapter(Me).Sort( ... ) method, which works if I force the IsReadOnly property for the list to false.  When I don't do that, I get a  "Changing an element is an invalid operation" exception. 

I would like to just have a editable collection of readonly objects (?) so I can sort, but not modify the results of what I got, but that doesn't work (BusinessListBase doesn't let me do that).

Is there any way that I can do a sort on this list?  I need to do it after the objects have been created, which is taken care of, but I need to be able to do it after that to _ensure_ the proper order. 

I have considered going the route of making a new property, and creating a new List(Of T) that is returned when that property is accessed, but it would be really nice to just fix what I already have.

Any ideas?  All of the List(of T) sorting is actually implemented in the list, not as part of IList, so nothing else supports it directly.. 

// Andrew

awbacker replied on Tuesday, August 26, 2008

There is a workaround, simpler than I thought.  I can set IsReadOnly=true inside this method on the list class, and then do the sorting, resting the flag afterwards.  Since the Set is protected, this is the only place it will work without reflection.

I was trying to move the sort call out of the list, where this wouldn't have worked, but I am now keeping it there and calling it through a custom function on the list. 

Here is the code I used, if anyone is interested:

Public Class MyDetailList

    Public
Sub SortByCountDescending()
    '-- sort, but we need to set readonly to 'false' first so it doesn't
    '-- throw an exception (you can't sort a RO list).  .Adapter doest work with Generic comparers
        IsReadOnly =
False
        ArrayList.Adapter(Me).Sort(New DescendingSortComparer)
        IsReadOnly =
True
    End Sub

    ''' <summary>Do a normal compare, but reverse the compairson results for desc ordering</summary>
    Private Class DescendingSortComparer : Implements
IComparer
       
Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements IComparer.
Compare
           
Return DirectCast(y, MyDetail).Count.CompareToCType(x,MyrDetail).PriorsCount  )
        End
Function
    End
Class
    ....
    ...

End Class

Copyright (c) Marimer LLC