Condividi tramite


Usare le IComparable interfacce e IComparer in Visual CSharp

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 IComparergià , è 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.Collectionsdella 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 IComparere 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.

  1. In Visual C# creare un nuovo progetto applicazione console. Assegnare all'applicazione il nome ConsoleEnum.

  2. 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();
           }
       }
    }
    
  3. Aggiungere una classe al progetto. Assegnare alla classe il nome Car.

  4. 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();
          }
    
       }
    }
    
  5. 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