IStructuralComparable Интерфейс
Определение
Важно!
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Поддерживает структурное сравнение объектов коллекции.
public interface class IStructuralComparable
public interface IStructuralComparable
type IStructuralComparable = interface
Public Interface IStructuralComparable
- Производный
Примеры
В следующем примере создается массив Tuple<T1,T2,T3,T4,T5,T6> объектов , содержащий данные о населении для трех городов США с 1960 по 2000 год. Первым компонентом sextuple является название города. Остальные пять компонентов представляют население с десятилетними интервалами с 1960 по 2000 год.
Класс PopulationComparer
предоставляет реализацию IComparer , которая позволяет отсортировать массив sextuples по любому из его компонентов. Классу в его конструкторе 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 .
Универсальные классы кортежей (, , и т. д.) и Array класс предоставляют явные IStructuralComparable реализации интерфейса. Tuple<T1,T2,T3>Tuple<T1,T2>Tuple<T1> Путем приведения (в C#) или преобразования (в Visual Basic) текущего экземпляра массива или кортежа в IStructuralComparable значение интерфейса и предоставления IComparer реализации в качестве аргумента CompareTo для метода можно определить пользовательский порядок сортировки для массива или коллекции. Однако в большинстве случаев метод не вызывается CompareTo напрямую. Вместо этого метод вызывается с помощью методов сортировки, CompareTo таких как Sort(Array, IComparer). В этом случае вы определяете IComparer свою реализацию и передаете ее в качестве аргумента в метод сортировки или конструктор класса объекта коллекции. Затем CompareTo метод с пользовательским компаратором вызывается автоматически при сортировке коллекции.
Методы
CompareTo(Object, IComparer) |
Определяет позицию текущего объекта коллекции относительно другого объекта в порядке сортировки (находится перед другим объектов, на одной позиции с ним или после другого объекта). |