/>
Se creiamo un array di variabili String e volessimo riordinarli sarebbe sufficiente chiamare il metodo Array.Sort(nostro_Array) , ma se costruiamo un nuovo tipo di oggetto, e ne inseriamo una certa quantità in un array e tentassimo di usare lo stesso metodo Sort, cosa accadrebbe?
IComparable
* Avviate VB 2008 EE e selezionate un progetto console.
* Dal menù Progetto scegliete la voce "Aggiungi Classe" e nella finestra che appare digitate "Car"
* Inserite questo codice di esempio:
Public Class Car Private _marca As String Private _modello As String Private _tipo_auto As String Public Property Marca() As String Get Return _marca End Get Set(ByVal value As String) _marca = value End Set End Property Public Property Modello() As String Get Return _modello End Get Set(ByVal value As String) _modello = value End Set End Property Public Property Tipo_Auto() As String Get Return _tipo_auto End Get Set(ByVal value As String) _tipo_auto = value End Set End Property Public Sub New(ByVal marca As String, ByVal modello As String, ByVal tipo_auto As String) _marca = marca _modello = modello _tipo_auto = tipo_auto End Sub End Class
* In "Esplora Soluzioni" selezionate Module1.vb e inserite le seguenti righe:
Module Module1 Sub Main() Console.WriteLine("*****Interfaccia IComparable*****") Dim automobili(4) As Car automobili(0) = New Car("Fiat", "Bravo", "Berlina") automobili(1) = New Car("Ford", "Kuga", "Crossover") automobili(2) = New Car("Renault", "Megane GrandTour", "Station Wagon") automobili(3) = New Car("Chevrolet", "Matiz", "City Car") automobili(4) = New Car("Ferrari", "612 Scaglietti", "Sportiva") For Each c As Car In automobili Console.WriteLine("Marca: {0} Modello: {1} Tipo: {2}", c.Marca, c.Modello, c.Tipo_Auto) Next Console.ReadLine() End Sub End Module
Eseguite il progetto e vedrete qualcosa di simile:
Adesso aggiungete la riga in ROSSO e provate ad eseguire nuovamente il progetto.
Module Module1
Sub Main()
Console.WriteLine("*****Interfaccia IComparable*****")
Dim automobili(4) As Car
automobili(0) = New Car("Fiat", "Bravo", "Berlina")
automobili(1) = New Car("Ford", "Kuga", "Crossover")
automobili(2) = New Car("Renault", "Megane GrandTour", "Station Wagon")
automobili(3) = New Car("Chevrolet", "Matiz", "City Car")
automobili(4) = New Car("Ferrari", "612 Scaglietti", "Sportiva")
Array.Sort(automobili)
For Each c As Car In automobili
Console.WriteLine("Marca: {0} Modello: {1} Tipo: {2}", c.Marca, c.Modello, c.Tipo_Auto)
Next
Console.ReadLine()
End Sub
End Module
Il metodo Array.Sort funziona correttamente su i tipi semplici, come Integer e String, ma ovviamente genera un'eccezione per i tipi più complessi per i quali non è chiaro in che modo definire un qualsiasi riordinamento.
A ben pensarci non è proprio scontato che gli elementi della lista vadano ordinati rispetto alla Marca piuttosto che al Modello o al Tipo_Auto.
Per risolvere questo tipo di problematica per i nuovi tipi di dati, in questo caso la nostra classe Car, possiamo usare l'interfaccia IComparable con la quale definire una SOLA tipologia di chiave per l'organizzazione dei dati.
Per poter realizzare quanto esposto bisogna implementare l'interfaccia IComparable e scrivere il codice necessario per definire il tipo di riordinamento attraverso la definizione del metodo CompareTo(...).
Supponendo di volere organizzare i dati in base alla Marca potete aggiungere il seguente codice alla classe Car:
Public Class Car Implements IComparable Private _marca As String Private _modello As String Private _tipo_auto As String Public Property Marca() As String Get Return _marca End Get Set(ByVal value As String) _marca = value End Set End Property Public Property Modello() As String Get Return _modello End Get Set(ByVal value As String) _modello = value End Set End Property Public Property Tipo_Auto() As String Get Return _tipo_auto End Get Set(ByVal value As String) _tipo_auto = value End Set End Property Public Sub New(ByVal marca As String, ByVal modello As String, ByVal tipo_auto As String) _marca = marca _modello = modello _tipo_auto = tipo_auto End Sub Public Function CompareTo(ByVal obj As Object) As Integer Implements System.IComparable.CompareTo If obj Is Nothing Then Return 1 Dim temp As Car = CType(obj, Car) Return String.Compare(Me._marca, temp._marca, True) End Function End Class
Adesso provate ad eseguire nuovamente il progetto e vedrete che tutto funziona perfettamente: la lista dei dati viene ordinata in base alla Marca dell'auto.
IComparer
Se desiderate che la lista possa essere riordinata in base a differenti criteri e non ad uno soltanto, si può utilizzare l'interfaccia IComparer.
Per poter implementare questo tipo di interfaccia è necessario creare una nuova classe che contiene la definizione del nuovo metodo di riorganizzazione della lista per ogni criterio di classificazione, usando il suo unico metodo Compare.
Volendo costruire due nuovi metodi di riordinamento su chiave Modello e Tipo_Auto bisogna fare quanto segue:
- Dal menù progetto scegliete la voce "Aggiungi Classe" e digitate il nome ModelloComparer, quindi inserite il seguente codice:
Public Class ModelloComparer Implements IComparer Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer _ Implements System.Collections.IComparer.Compare Dim c1 As Car = CType(x, Car) Dim c2 As Car = CType(y, Car) Return String.Compare(c1.Modello, c2.Modello) End Function End Class
- Dal menù progetto scegliete la voce "Aggiungi Classe" e digitate il nome Tipo_AutoComparer, quindi inserite il seguente codice:
Public Class Tipo_AutoComparer Implements IComparer Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer _ Implements System.Collections.IComparer.Compare Dim c1 As Car = CType(x, Car) Dim c2 As Car = CType(y, Car) Return String.Compare(c1.Tipo_Auto, c2.Tipo_Auto) End Function End Class
- A questo punto modificate Module1.vb in questo modo:
Module Module1 Sub Main() Console.WriteLine("*****Interfaccia IComparable*****") Dim automobili(4) As Car automobili(0) = New Car("Fiat", "Bravo", "Berlina") automobili(1) = New Car("Ford", "Kuga", "Crossover") automobili(2) = New Car("Renault", "Megane GrandTour", "Station Wagon") automobili(3) = New Car("Chevrolet", "Matiz", "City Car") automobili(4) = New Car("Ferrari", "612 Scaglietti", "Sportiva") Array.Sort(automobili) For Each c As Car In automobili Console.WriteLine("Marca: {0} Modello: {1} Tipo: {2}", c.Marca, c.Modello, c.Tipo_Auto) Next Console.WriteLine() Console.WriteLine("*****Riordinamento per MODELLO*****") Array.Sort(automobili, New ModelloComparer()) For Each c As Car In automobili Console.WriteLine("Marca: {0} Modello: {1} Tipo: {2}", c.Marca, c.Modello, c.Tipo_Auto) Next Console.WriteLine() Console.WriteLine("*****Riordinamento per Tipo_Auto*****") Array.Sort(automobili, New Tipo_AutoComparer()) For Each c As Car In automobili Console.WriteLine("Marca: {0} Modello: {1} Tipo: {2}", c.Marca, c.Modello, c.Tipo_Auto) Next Console.ReadLine() End Sub End Module
Dovreste vedere una finestra simile alla seguente: