IStructuralComparable Интерфейс

Определение

Поддерживает структурное сравнение объектов коллекции.

public interface class IStructuralComparable
public interface IStructuralComparable
type IStructuralComparable = interface
Public Interface IStructuralComparable
Производный

Примеры

В следующем примере создается массив Tuple<T1,T2,T3,T4,T5,T6> объектов, содержащий данные о населении для трех городов США с 1960 до 2000. Первым компонентом из шести компонентов является название города. Оставшиеся пять компонентов представляют собой совокупность с интервалом в десять лет от 1960 до 2000.

PopulationComparerКласс предоставляет IComparer реализацию, которая позволяет сортировать массив секступлес по любому из его компонентов. В конструкторе передаются два значения PopulationComparer : расположение компонента, определяющего порядок сортировки, и логическое значение, указывающее, сортируются ли объекты кортежа в порядке возрастания или убывания.

Затем в этом примере элементы массива отображаются в несортированном порядке, сортируются по третьему компоненту (заполнение в 1970) и отображаются, а затем сортируются по шестому компоненту (заполнение в 2000) и отображаются. Обратите внимание, что в этом примере метод не вызывается напрямую CompareTo . Метод вызывается неявно Sort(Array, IComparer) методом для каждого объекта кортежа в массиве.

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)

Комментарии

IStructuralComparableИнтерфейс позволяет реализовать пользовательские сравнения для элементов коллекции. Иными словами, можно точно определить, что означает для одного объекта коллекции, который должен предшествовать, следовать или находиться в том же положении в порядке сортировки, что и второй объект коллекции. Затем можно указать, что это определение должно использоваться с типом коллекции, который принимает IStructuralComparable интерфейс.

Интерфейс содержит один элемент, CompareTo который определяет, является ли текущий объект коллекции меньшим, равным или большим, чем второй объект в порядке сортировки. Фактическое сравнение элементов или элементов в текущем экземпляре с элементами во втором объекте осуществляется IComparer реализацией интерфейса, которая содержит определение пользовательского сравнения.

Примечание

IStructuralComparableИнтерфейс поддерживает только структурные сравнения для сортировки или упорядочения. IStructuralEquatableИнтерфейс поддерживает пользовательские сравнения для структурного равенства.

платформа .NET Framework предоставляет два компаратора по умолчанию. Одна из них возвращается StructuralComparisons.StructuralComparer свойством, а другая возвращается Comparer<T>.Default свойством.

Универсальные классы кортежей ( Tuple<T1> , Tuple<T1,T2> , Tuple<T1,T2,T3> и т. д.) и Array класс предоставляют явные реализации IStructuralComparable интерфейса. путем приведения (в C#) или преобразования (в Visual Basic) текущего экземпляра массива или кортежа в IStructuralComparable значение интерфейса и предоставления IComparer реализации в качестве аргумента для CompareTo метода можно определить пользовательский порядок сортировки для массива или коллекции. Однако CompareTo в большинстве случаев метод не вызывается напрямую. Вместо этого CompareTo метод вызывается такими методами сортировки, как Sort(Array, IComparer) . В этом случае необходимо определить IComparer реализацию и передать ее в качестве аргумента в конструктор класса метода сортировки или объекта коллекции. CompareToМетод с пользовательским компаратором затем вызывается автоматически при сортировке коллекции.

Методы

CompareTo(Object, IComparer)

Определяет позицию текущего объекта коллекции относительно другого объекта в порядке сортировки (находится перед другим объектов, на одной позиции с ним или после другого объекта).

Применяется к

См. также раздел