Condividi tramite


IStructuralComparable Interfaccia

Definizione

Supporta il confronto strutturale degli oggetti raccolta.

public interface class IStructuralComparable
public interface IStructuralComparable
type IStructuralComparable = interface
Public Interface IStructuralComparable
Derivato

Esempio

L'esempio seguente crea una matrice di oggetti che contiene i dati sulla Tuple<T1,T2,T3,T4,T5,T6> popolazione per tre città degli Stati Uniti dal 1960 al 2000. Il primo componente della sextuple è il nome della città. I cinque componenti rimanenti rappresentano la popolazione a intervalli di dieci anni dal 1960 al 2000.

La PopulationComparer classe fornisce un'implementazione IComparer che consente di ordinare la matrice di sextuple in base a uno dei relativi componenti. Due valori vengono forniti alla PopulationComparer classe nel relativo costruttore: la posizione del componente che definisce l'ordinamento e un valore booleano che indica se gli oggetti tupla devono essere ordinati in ordine crescente o decrescente.

L'esempio visualizza quindi gli elementi nella matrice in ordine non ordinato, li ordina in base al terzo componente (popolazione nel 1970) e li visualizza e li ordina in base al sesto componente (popolazione nel 2000) e li visualizza. Si noti che l'esempio non chiama direttamente il CompareTo metodo . Il metodo viene chiamato in modo implicito dal Sort(Array, IComparer) metodo per ogni oggetto tupla nella matrice.

using System;
using System.Collections;
using System.Collections.Generic;

public class PopulationComparer<T1, T2, T3, T4, T5, T6> : IComparer
{
   private int itemPosition;
   private int multiplier = -1;

   public PopulationComparer(int component) : this(component, true)
   { }

   public PopulationComparer(int component, bool descending)
   {
      if (!descending) multiplier = 1;

      if (component <= 0 || component > 6)
         throw new ArgumentException("The component argument is out of range.");

      itemPosition = component;
   }

   public int Compare(object x, object y)
   {
      var tX = x as Tuple<T1, T2, T3, T4, T5, T6>;
      if (tX == null)
      {
         return 0;
      }
      else
      {
         var tY = y as Tuple<T1, T2, T3, T4, T5, T6>;
         switch (itemPosition)
         {
            case 1:
               return Comparer<T1>.Default.Compare(tX.Item1, tY.Item1) * multiplier;
            case 2:
               return Comparer<T2>.Default.Compare(tX.Item2, tY.Item2) * multiplier;
            case 3:
               return Comparer<T3>.Default.Compare(tX.Item3, tY.Item3) * multiplier;
            case 4:
               return Comparer<T4>.Default.Compare(tX.Item4, tY.Item4) * multiplier;
            case 5:
               return Comparer<T5>.Default.Compare(tX.Item5, tY.Item5) * multiplier;
            case 6:
               return Comparer<T6>.Default.Compare(tX.Item6, tY.Item6) * multiplier;
            default:
               return Comparer<T1>.Default.Compare(tX.Item1, tY.Item1) * multiplier;
         }
      }
   }
}

public class Example
{
   public static void Main()
   {
      // Create array of sextuple with population data for three U.S.
      // cities, 1960-2000.
      Tuple<string, int, int, int, int, int>[] cities =
           { Tuple.Create("Los Angeles", 2479015, 2816061, 2966850, 3485398, 3694820),
             Tuple.Create("New York", 7781984, 7894862, 7071639, 7322564, 8008278),
             Tuple.Create("Chicago", 3550904, 3366957, 3005072, 2783726, 2896016) };

      // Display array in unsorted order.
      Console.WriteLine("In unsorted order:");
      foreach (var city in cities)
         Console.WriteLine(city.ToString());
      Console.WriteLine();

      Array.Sort(cities, new PopulationComparer<string, int, int, int, int, int>(3));

      // Display array in sorted order.
      Console.WriteLine("Sorted by population in 1970:");
      foreach (var city in cities)
         Console.WriteLine(city.ToString());
      Console.WriteLine();

      Array.Sort(cities, new PopulationComparer<string, int, int, int, int, int>(6));

      // Display array in sorted order.
      Console.WriteLine("Sorted by population in 2000:");
      foreach (var city in cities)
         Console.WriteLine(city.ToString());
   }
}
// The example displays the following output:
//    In unsorted order:
//    (Los Angeles, 2479015, 2816061, 2966850, 3485398, 3694820)
//    (New York, 7781984, 7894862, 7071639, 7322564, 8008278)
//    (Chicago, 3550904, 3366957, 3005072, 2783726, 2896016)
//    
//    Sorted by population in 1970:
//    (New York, 7781984, 7894862, 7071639, 7322564, 8008278)
//    (Chicago, 3550904, 3366957, 3005072, 2783726, 2896016)
//    (Los Angeles, 2479015, 2816061, 2966850, 3485398, 3694820)
//    
//    Sorted by population in 2000:
//    (New York, 7781984, 7894862, 7071639, 7322564, 8008278)
//    (Los Angeles, 2479015, 2816061, 2966850, 3485398, 3694820)
//    (Chicago, 3550904, 3366957, 3005072, 2783726, 2896016)
Imports System.Collections
Imports System.Collections.Generic

Public Class PopulationComparer(Of T1, T2, T3, T4, T5, T6) : Implements IComparer
   Private itemPosition As Integer
   Private multiplier As Integer = -1
      
   Public Sub New(component As Integer)
      Me.New(component, True)
   End Sub
   
   Public Sub New(component As Integer, descending As Boolean)
      If Not descending Then multiplier = 1
      
      If component <= 0 Or component > 6 Then 
         Throw New ArgumentException("The component argument is out of range.")
      End If
      itemPosition = component
   End Sub 
   
   Public Function Compare(x As Object, y As Object) As Integer _
                   Implements IComparer.Compare
 
      Dim tX = TryCast(x, Tuple(Of T1, T2, T3, T4, T5, T6))
      If tX Is Nothing Then
         Return 0
      Else
         Dim tY = DirectCast(y, Tuple(Of T1, T2, T3, T4, T5, T6))
         Select Case itemPosition
            Case 1
               Return Comparer(Of T1).Default.Compare(tX.Item1, tY.Item1) * multiplier
            Case 2
               Return Comparer(Of T2).Default.Compare(tX.Item2, tY.Item2) * multiplier
            Case 3
               Return Comparer(Of T3).Default.Compare(tX.Item3, tY.Item3) * multiplier
            Case 4
               Return Comparer(Of T4).Default.Compare(tX.Item4, tY.Item4) * multiplier
            Case 5
               Return Comparer(Of T5).Default.Compare(tX.Item5, tY.Item5) * multiplier
            Case 6
               Return Comparer(Of T6).Default.Compare(tX.Item6, tY.Item6) * multiplier
            ' This should never happen.
            Case Else
               Return 0
         End Select      
      End If
   End Function
End Class

Module Example
   Public Sub Main()
      ' Create array of sextuple with population data for three U.S. 
      ' cities, 1960-2000.
      Dim cities() = 
          { Tuple.Create("Los Angeles", 2479015, 2816061, 2966850, 3485398, 3694820),
            Tuple.Create("New York", 7781984, 7894862, 7071639, 7322564, 8008278),  
            Tuple.Create("Chicago", 3550904, 3366957, 3005072, 2783726, 2896016) } 
      
      ' Display array in unsorted order.
      Console.WriteLine("In unsorted order:")
      For Each city In cities
         Console.WriteLine(city.ToString())
      Next
      Console.WriteLine()
      
      Array.Sort(cities, New PopulationComparer(Of String, Integer, Integer, Integer, Integer, Integer)(3)) 
                           
      ' Display array in sorted order.
      Console.WriteLine("Sorted by population in 1970:")
      For Each city In cities
         Console.WriteLine(city.ToString())
      Next
      Console.WriteLine()
      
      Array.Sort(cities, New PopulationComparer(Of String, Integer, Integer, Integer, Integer, Integer)(6))
                           
      ' Display array in sorted order.
      Console.WriteLine("Sorted by population in 2000:")
      For Each city In cities
         Console.WriteLine(city.ToString())
      Next
   End Sub
End Module
' The example displays the following output:
'    In unsorted order:
'    (Los Angeles, 2479015, 2816061, 2966850, 3485398, 3694820)
'    (New York, 7781984, 7894862, 7071639, 7322564, 8008278)
'    (Chicago, 3550904, 3366957, 3005072, 2783726, 2896016)
'    
'    Sorted by population in 1970:
'    (New York, 7781984, 7894862, 7071639, 7322564, 8008278)
'    (Chicago, 3550904, 3366957, 3005072, 2783726, 2896016)
'    (Los Angeles, 2479015, 2816061, 2966850, 3485398, 3694820)
'    
'    Sorted by population in 2000:
'    (New York, 7781984, 7894862, 7071639, 7322564, 8008278)
'    (Los Angeles, 2479015, 2816061, 2966850, 3485398, 3694820)
'    (Chicago, 3550904, 3366957, 3005072, 2783726, 2896016)

Commenti

L'interfaccia IStructuralComparable consente di implementare confronti personalizzati per i membri della raccolta. In altre parole, è possibile definire esattamente ciò che significa che un oggetto raccolta precede, segue o si trova nella stessa posizione nell'ordinamento come secondo oggetto raccolta. È quindi possibile specificare che questa definizione venga usata con un tipo di raccolta che accetta l'interfaccia IStructuralComparable .

L'interfaccia ha un singolo membro, CompareTo, che determina se l'oggetto raccolta corrente è minore, uguale o maggiore di un secondo oggetto nell'ordinamento. Il confronto effettivo dei membri o degli elementi nell'istanza corrente con quelli in un secondo oggetto viene eseguito da un'implementazione IComparer dell'interfaccia, che contiene la definizione del confronto personalizzato.

Annotazioni

L'interfaccia IStructuralComparable supporta solo confronti strutturali per l'ordinamento o l'ordinamento. L'interfaccia IStructuralEquatable supporta confronti personalizzati per l'uguaglianza strutturale.

.NET Framework offre due comparer predefiniti. Uno viene restituito dalla StructuralComparisons.StructuralComparer proprietà . L'altro viene restituito dalla Comparer<T>.Default proprietà .

Le classi di tuple generiche (, , e così via) e la Array classe forniscono implementazioni esplicite dell'interfacciaIStructuralComparable. Tuple<T1,T2,T3>Tuple<T1,T2>Tuple<T1> Eseguendo il cast (in C#) o la conversione (in Visual Basic) dell'istanza corrente di una matrice o di una tupla in un IStructuralComparable valore di interfaccia e fornendo l'implementazione IComparer come argomento al metodo, è possibile definire un ordinamento personalizzato per la matrice o la CompareTo raccolta. Tuttavia, non si chiama direttamente il CompareTo metodo nella maggior parte dei casi. Al contrario, il metodo viene chiamato tramite l'ordinamento CompareTo di metodi come Sort(Array, IComparer). In questo caso, si definisce l'implementazione IComparer e la si passa come argomento a un metodo di ordinamento o al costruttore della classe dell'oggetto raccolta. Il CompareTo metodo con l'operatore di confronto personalizzato viene quindi chiamato automaticamente ogni volta che viene ordinata la raccolta.

Metodi

Nome Descrizione
CompareTo(Object, IComparer)

Determina se l'oggetto raccolta corrente precede, si verifica nella stessa posizione di o segue un altro oggetto nell'ordinamento.

Si applica a

Vedi anche