Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Usare le
Questo articolo descrive l'uso di IComparer
interfacce e IComparable
in Visual C#.
Versione originale del prodotto: Visual C#
Numero KB originale: 320727
Riepilogo
Le IComparable
interfacce e IComparer
sono descritte nello stesso articolo per due motivi. Queste interfacce vengono spesso usate insieme. Anche se le interfacce sono simili e hanno nomi simili, servono scopi diversi.
Se si dispone di una matrice di tipi (ad esempio stringa o integer) che supporta IComparer
già , è possibile ordinare tale matrice senza fornire alcun riferimento esplicito a IComparer
. In tal caso, viene eseguito il cast degli elementi della matrice all'implementazione predefinita di IComparer
(Comparer.Default
). Tuttavia, se si vuole fornire funzionalità di ordinamento o confronto per gli oggetti personalizzati, è necessario implementare una o entrambe queste interfacce.
Questo articolo fa riferimento allo spazio dei nomi System.Collections
della libreria di classi di Microsoft .NET Framework.
IComparable
Il ruolo di IComparable
consiste nel fornire un metodo di confronto tra due oggetti di un particolare tipo. È necessario se si vuole fornire qualsiasi funzionalità di ordinamento per l'oggetto. Si pensi a IComparable
fornire un ordinamento predefinito per gli oggetti. Ad esempio, se si dispone di una matrice di oggetti del tipo e si chiama il Sort
metodo su tale matrice, IComparable
viene fornito il confronto degli oggetti durante l'ordinamento. Quando si implementa l'interfaccia IComparable
, è necessario implementare il CompareTo
metodo , come indicato di seguito:
// Implement IComparable CompareTo method - provide default sort order.
int IComparable.CompareTo(object obj)
{
Car c=(Car)obj;
return String.Compare(this.make,c.make);
}
Il confronto nel metodo è diverso a seconda del tipo di dati del valore confrontato. String.Compare
viene utilizzato in questo esempio perché la proprietà scelta per il confronto è una stringa.
IComparer
Il ruolo di è fornire più meccanismi di IComparer
confronto. Ad esempio, è possibile specificare l'ordinamento della classe in diversi campi o proprietà, in ordine crescente e decrescente nello stesso campo o in entrambi i campi.
L'uso IComparer
è un processo in due passaggi. Prima di tutto, dichiarare una classe che implementa IComparer
e quindi implementare il Compare
metodo :
private class SortYearAscendingHelper : IComparer
{
int IComparer.Compare(object a, object b)
{
Car c1=(Car)a;
Car c2=(Car)b;
if (c1.year > c2.year)
return 1;
if (c1.year < c2.year)
return -1;
else
return 0;
}
}
Note
Il IComparer.Compare
metodo richiede un confronto terziario. 1, 0 o -1 viene restituito a seconda che un valore sia maggiore, uguale o minore dell'altro. L'ordinamento (crescente o decrescente) può essere modificato cambiando gli operatori logici in questo metodo.
Il secondo passaggio consiste nel dichiarare un metodo che restituisce un'istanza dell'oggetto IComparer
:
public static IComparer SortYearAscending()
{
return (IComparer) new SortYearAscendingHelper();
}
In questo esempio, l'oggetto viene usato come secondo argomento quando si chiama il metodo di Array.Sort
overload che accetta IComparer
. L'uso di IComparer
non è limitato alle matrici. Viene accettato come argomento in molte classi di raccolta e controllo diverse.
Esempio dettagliato
Nell'esempio seguente viene illustrato l'uso di queste interfacce. Per illustrare IComparer
e IComparable
, viene creata una classe denominata Car
. L'oggetto Car
ha le proprietà make e year. Un ordinamento crescente per il campo make viene abilitato tramite l'interfaccia IComparable
e un ordinamento decrescente sul campo make viene abilitato tramite l'interfaccia IComparer
. Sia gli ordinamenti crescente che decrescente vengono forniti per la proprietà year tramite IComparer
.
In Visual C# creare un nuovo progetto applicazione console. Assegnare all'applicazione il nome ConsoleEnum.
Rinominare Program.cs come Host.cs e quindi sostituire il codice con il codice seguente.
using System; namespace ConsoleEnum { class host { [STAThread] static void Main(string[] args) { // Create an array of Car objects. Car[] arrayOfCars= new Car[6] { new Car("Ford",1992), new Car("Fiat",1988), new Car("Buick",1932), new Car("Ford",1932), new Car("Dodge",1999), new Car("Honda",1977) }; // Write out a header for the output. Console.WriteLine("Array - Unsorted\n"); foreach(Car c in arrayOfCars) Console.WriteLine(c.Make + "\t\t" + c.Year); // Demo IComparable by sorting array with "default" sort order. Array.Sort(arrayOfCars); Console.WriteLine("\nArray - Sorted by Make (Ascending - IComparable)\n"); foreach(Car c in arrayOfCars) Console.WriteLine(c.Make + "\t\t" + c.Year); // Demo ascending sort of numeric value with IComparer. Array.Sort(arrayOfCars,Car.SortYearAscending()); Console.WriteLine("\nArray - Sorted by Year (Ascending - IComparer)\n"); foreach(Car c in arrayOfCars) Console.WriteLine(c.Make + "\t\t" + c.Year); // Demo descending sort of string value with IComparer. Array.Sort(arrayOfCars,Car.SortMakeDescending()); Console.WriteLine("\nArray - Sorted by Make (Descending - IComparer)\n"); foreach(Car c in arrayOfCars) Console.WriteLine(c.Make + "\t\t" + c.Year); // Demo descending sort of numeric value using IComparer. Array.Sort(arrayOfCars,Car.SortYearDescending()); Console.WriteLine("\nArray - Sorted by Year (Descending - IComparer)\n"); foreach(Car c in arrayOfCars) Console.WriteLine(c.Make + "\t\t" + c.Year); Console.ReadLine(); } } }
Aggiungere una classe al progetto. Assegnare alla classe il nome Car.
Sostituire il codice in Car.cs con il codice seguente:
using System; using System.Collections; namespace ConsoleEnum { public class Car : IComparable { // Beginning of nested classes. // Nested class to do ascending sort on year property. private class SortYearAscendingHelper: IComparer { int IComparer.Compare(object a, object b) { Car c1=(Car)a; Car c2=(Car)b; if (c1.year > c2.year) return 1; if (c1.year < c2.year) return -1; else return 0; } } // Nested class to do descending sort on year property. private class SortYearDescendingHelper: IComparer { int IComparer.Compare(object a, object b) { Car c1=(Car)a; Car c2=(Car)b; if (c1.year < c2.year) return 1; if (c1.year > c2.year) return -1; else return 0; } } // Nested class to do descending sort on make property. private class SortMakeDescendingHelper: IComparer { int IComparer.Compare(object a, object b) { Car c1=(Car)a; Car c2=(Car)b; return String.Compare(c2.make,c1.make); } } // End of nested classes. private int year; private string make; public Car(string Make,int Year) { make=Make; year=Year; } public int Year { get {return year;} set {year=value;} } public string Make { get {return make;} set {make=value;} } // Implement IComparable CompareTo to provide default sort order. int IComparable.CompareTo(object obj) { Car c=(Car)obj; return String.Compare(this.make,c.make); } // Method to return IComparer object for sort helper. public static IComparer SortYearAscending() { return (IComparer) new SortYearAscendingHelper(); } // Method to return IComparer object for sort helper. public static IComparer SortYearDescending() { return (IComparer) new SortYearDescendingHelper(); } // Method to return IComparer object for sort helper. public static IComparer SortMakeDescending() { return (IComparer) new SortMakeDescendingHelper(); } } }
Eseguire il progetto. L'output seguente viene visualizzato nella finestra Console :
Array - Unsorted Ford 1992 Fiat 1988 Buick 1932 Ford 1932 Dodge 1999 Honda 1977 Array - Sorted by Make (Ascending - IComparable) Buick 1932 Dodge 1999 Fiat 1988 Ford 1932 Ford 1992 Honda 1977 Array - Sorted by Year (Ascending - IComparer) Ford 1932 Buick 1932 Honda 1977 Fiat 1988 Ford 1992 Dodge 1999 Array - Sorted by Make (Descending - IComparer) Honda 1977 Ford 1932 Ford 1992 Fiat 1988 Dodge 1999 Buick 1932 Array - Sorted by Year (Descending - IComparer) Dodge 1999 Ford 1992 Fiat 1988 Honda 1977 Buick 1932 Ford 1932