Oppure

Loading
19/12/10 14:42
dedalux
Salve a tutti,
sto creando una classe di tipo Collection(Of T) che eredita da ObservableCollection(Of T), e voglio creare un metodo Order per ordinare la classe in base ad una proprietà di T che dev'essere passata come parametro del metodo.
Per fare un semplice esempio:
Class Libro

    Dim _Titolo As String
    Public ReadOnly Property Titolo As String
        Get
            Return _Titolo
        End Get
    End Property

End Class

Class SortableObservableCollection(Of T)

    Public Sub Sort(ByVal [Property] As PropertyInfo)
        'Secondo la mia implementazione dell'algoritmo InsertionSort (che fa schifo, ma un po alla volta li implemento tutti)
        'dato che utilizzo un ciclo for each, arrivo al punto in cui devo fare Item(i).[Property].Valore < Item(i-1).[Property].Valore
        '
        'Come fare?
    End Sub

End Class


Tempo fa Il Totem mi aveva consigliato di utilizzare la classe PropertyInfo.
Ma poi ho scoperto che c'era una soluzione migliore al mio problema e ho cambiato strada.
In questo caso non ho altre idee, e ad ogni modo, vorrei definitivamente capire come si fa.

Mi potreste dare una mano?
Grazie davvero! :k:
aaa
19/12/10 15:08
HeDo
purtroppo non è furbo fare così, esistono già dei metodi di estensione che si occupano di ordinare le collection, e tramite linq puoi anche specificare il campo sul quale fare l'ordinamento.

Utilizzare propertyinfo è fattibile ma devi arrivarci con la reflection al campo su cui vuoi effettuare il sorting, e se non sei ferrato in .NET potrebbe presentare qualche problema.

Se il tuo è un programma di esempio ti consiglio di utilizzare collection di tipi semplici, cioè non classi.

aaa
19/12/10 15:45
dedalux
No il programma è per un utilizzo personale.

Il punto è che volevo creare dei miei metodi di ordinamento, per arrivare ad utilizzare il quicksort (che dovrebbe essere il più veloce in assoluto da quanto ho letto), che spero possa essere più rapido rispetto all'algoritmo di ordinamento utilizzato dalla classe base (o magari si basa già sul quicksort).
Sta di fatto che se ho una collezione con 300-400 000 oggetti, nell'ordinarla non è che sia tanto veloce..
aaa
19/12/10 16:08
HeDo
Postato originariamente da dedalux:

No il programma è per un utilizzo personale.

Il punto è che volevo creare dei miei metodi di ordinamento, per arrivare ad utilizzare il quicksort (che dovrebbe essere il più veloce in assoluto da quanto ho letto), che spero possa essere più rapido rispetto all'algoritmo di ordinamento utilizzato dalla classe base (o magari si basa già sul quicksort).
Sta di fatto che se ho una collezione con 300-400 000 oggetti, nell'ordinarla non è che sia tanto veloce..


il quicksort è già utilizzato internamente a tutti i metodi sort di tutte le collection. A riprova di questo posto il sorgente della classe ArraySortHelper che viene utilizzata internamente al framework .NET per ordinare qualsiasi tipo di collezione:



<TypeDependency("System.Collections.Generic.GenericArraySortHelper`2")> _
Friend Class ArraySortHelper(Of TKey, TValue)
    Implements IArraySortHelper(Of TKey, TValue)
    ' Methods
    <SecuritySafeCritical> _
    Public Shared Function CreateArraySortHelper() As IArraySortHelper(Of TKey, TValue)
        If GetType(IComparable(Of TKey)).IsAssignableFrom(GetType(TKey)) Then
            ArraySortHelper(Of TKey, TValue).defaultArraySortHelper = DirectCast(RuntimeTypeHandle.Allocate(GetType(GenericArraySortHelper(Of String, String)).TypeHandle.Instantiate(New Type() { GetType(TKey), GetType(TValue) })), IArraySortHelper(Of TKey, TValue))
        Else
            ArraySortHelper(Of TKey, TValue).defaultArraySortHelper = New ArraySortHelper(Of TKey, TValue)
        End If
        Return ArraySortHelper(Of TKey, TValue).defaultArraySortHelper
    End Function

    Friend Shared Sub QuickSort(ByVal keys As TKey(), ByVal values As TValue(), ByVal left As Integer, ByVal right As Integer, ByVal comparer As IComparer(Of TKey))
        Do
            Dim a As Integer = left
            Dim b As Integer = right
            Dim num3 As Integer = (a + ((b - a) >> 1))
            ArraySortHelper(Of TKey, TValue).SwapIfGreaterWithItems(keys, values, comparer, a, num3)
            ArraySortHelper(Of TKey, TValue).SwapIfGreaterWithItems(keys, values, comparer, a, b)
            ArraySortHelper(Of TKey, TValue).SwapIfGreaterWithItems(keys, values, comparer, num3, b)
            Dim y As TKey = keys(num3)
            Do
                Do While (comparer.Compare(keys(a), y) < 0)
                    a += 1
                Loop
                Do While (comparer.Compare(y, keys(b)) < 0)
                    b -= 1
                Loop
                If (a > b) Then
                    Exit Do
                End If
                If (a < b) Then
                    Dim local2 As TKey = keys(a)
                    keys(a) = keys(b)
                    keys(b) = local2
                    If (Not values Is Nothing) Then
                        Dim local3 As TValue = values(a)
                        values(a) = values(b)
                        values(b) = local3
                    End If
                End If
                a += 1
                b -= 1
            Loop While (a <= b)
            If ((b - left) <= (right - a)) Then
                If (left < b) Then
                    ArraySortHelper(Of TKey, TValue).QuickSort(keys, values, left, b, comparer)
                End If
                left = a
            Else
                If (a < right) Then
                    ArraySortHelper(Of TKey, TValue).QuickSort(keys, values, a, right, comparer)
                End If
                right = b
            End If
        Loop While (left < right)
    End Sub

    Public Sub Sort(ByVal keys As TKey(), ByVal values As TValue(), ByVal index As Integer, ByVal length As Integer, ByVal comparer As IComparer(Of TKey))
        Try 
            If ((comparer Is Nothing) OrElse (comparer Is Comparer(Of TKey).Default)) Then
                comparer = Comparer(Of TKey).Default
            End If
            ArraySortHelper(Of TKey, TValue).QuickSort(keys, values, index, (index + (length - 1)), comparer)
        Catch exception1 As IndexOutOfRangeException
            Dim objArray As Object() = New Object(3  - 1) {}
            objArray(1) = GetType(TKey).Name
            objArray(2) = comparer
            Throw New ArgumentException(Environment.GetResourceString("Arg_BogusIComparer", objArray))
        Catch exception As Exception
            Throw New InvalidOperationException(Environment.GetResourceString("InvalidOperation_IComparerFailed"), exception)
        End Try
    End Sub

    Private Shared Sub SwapIfGreaterWithItems(ByVal keys As TKey(), ByVal values As TValue(), ByVal comparer As IComparer(Of TKey), ByVal a As Integer, ByVal b As Integer)
        If (((a <> b) AndAlso (a <> b)) AndAlso (comparer.Compare(keys(a), keys(b)) > 0)) Then
            Dim local As TKey = keys(a)
            keys(a) = keys(b)
            keys(b) = local
            If (Not values Is Nothing) Then
                Dim local2 As TValue = values(a)
                values(a) = values(b)
                values(b) = local2
            End If
        End If
    End Sub


    ' Properties
    Public Shared ReadOnly Property [Default] As IArraySortHelper(Of TKey, TValue)
        Get
            Dim defaultArraySortHelper As IArraySortHelper(Of TKey, TValue) = ArraySortHelper(Of TKey, TValue).defaultArraySortHelper
            If (defaultArraySortHelper Is Nothing) Then
                defaultArraySortHelper = ArraySortHelper(Of TKey, TValue).CreateArraySortHelper
            End If
            Return defaultArraySortHelper
        End Get
    End Property


    ' Fields
    Private Shared defaultArraySortHelper As IArraySortHelper(Of TKey, TValue)
End Class



aaa
22/12/10 13:30
dedalux
Grazie HeDo per il chiarimento!
Scusandomi per la risposta tardiva, ho scopero questa sezione sul sito di Totem, totemslair.org/guide/… e vorrei fare una colletta per un erigergli un monumento... Qualcuno si aggrega? :rotfl:

No scherzi a parte, penso di aver risolto il mio problema, al massimo torno a scassare XD

Grazie ancora! :k:
aaa