Partilhar via


IStructuralComparable Interface

Definição

Dá suporte à comparação estrutural de objetos da coleção.

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

Exemplos

O exemplo a seguir cria uma matriz de Tuple<T1,T2,T3,T4,T5,T6> objetos que contém dados de população para três cidades dos EUA de 1960 a 2000. O primeiro componente da sextupla é o nome da cidade. Os cinco componentes restantes representam a população em intervalos de dez anos de 1960 a 2000.

A PopulationComparer classe fornece uma implementação IComparer que permite que a matriz de sextuplas seja classificada por qualquer um de seus componentes. Dois valores são fornecidos à PopulationComparer classe em seu construtor: a posição do componente que define a ordem de classificação e um valor booliano que indica se os objetos de tupla devem ser classificados em ordem crescente ou decrescente.

Em seguida, o exemplo exibe os elementos na matriz em ordem não classificada, classifica-os pelo terceiro componente (a população em 1970) e os exibe e os classifica pelo sexto componente (a população em 2000) e os exibe. Observe que o exemplo não chama diretamente o CompareTo método . O método é chamado implicitamente pelo Sort(Array, IComparer) método para cada objeto de tupla na matriz.

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)

Comentários

A IStructuralComparable interface permite implementar comparações personalizadas para membros da coleção. Ou seja, você pode definir precisamente o que significa para um objeto de coleção preceder, seguir ou ocorrer na mesma posição na ordem de classificação de um segundo objeto de coleção. Em seguida, você pode especificar que essa definição seja usada com um tipo de coleção que aceite a IStructuralComparable interface.

A interface tem um único membro, CompareTo, que determina se o objeto de coleção atual é menor que, igual a ou maior que um segundo objeto na ordem de classificação. A comparação real dos membros ou elementos na instância atual com aqueles em um segundo objeto é executada por uma IComparer implementação de interface, que contém a definição de sua comparação personalizada.

Observação

A IStructuralComparable interface dá suporte apenas a comparações estruturais para classificação ou ordenação. A IStructuralEquatable interface dá suporte a comparações personalizadas para igualdade estrutural.

O .NET Framework fornece dois comparadores padrão. Um é retornado pela StructuralComparisons.StructuralComparer propriedade ; o outro é retornado pela Comparer<T>.Default propriedade .

As classes de tupla genéricas (Tuple<T1>, Tuple<T1,T2>, Tuple<T1,T2,T3>e assim por diante) e a Array classe fornecem implementações explícitas da IStructuralComparable interface. Convertendo (em C#) ou convertendo (no Visual Basic) a instância atual de uma matriz ou tupla em um IStructuralComparable valor de interface e fornecendo sua IComparer implementação como um argumento para o CompareTo método , você pode definir uma ordem de classificação personalizada para a matriz ou coleção. No entanto, você não chama o CompareTo método diretamente na maioria dos casos. Em vez disso, o CompareTo método é chamado classificando métodos como Sort(Array, IComparer). Nesse caso, você define sua IComparer implementação e a passa como um argumento para um método de classificação ou construtor de classe do objeto de coleção. O CompareTo método com seu comparador personalizado é chamado automaticamente sempre que a coleção é classificada.

Métodos

CompareTo(Object, IComparer)

Determina se o objeto da coleção atual precede, ocorre na mesma posição ou segue a outro objeto na ordem de classificação.

Aplica-se a

Confira também