Поделиться через


IStructuralComparable Interface

Microsoft Silverlight will reach end of support after October 2021. Learn more.

Supports the structural comparison of collection objects.

Namespace:  System.Collections
Assembly:  mscorlib (in mscorlib.dll)

Syntax

'Declaration
Public Interface IStructuralComparable
public interface IStructuralComparable

The IStructuralComparable type exposes the following members.

Methods

  Name Description
Public method CompareTo Determines whether the current collection object precedes, occurs in the same position as, or follows another object in the sort order.

Top

Remarks

The IStructuralComparable interface enables you to implement customized comparisons for collection members. That is, you can define precisely what it means for one collection object to precede, follow, or occur in the same position in the sort order as a second collection object. You can then specify that this definition be used with a collection type that accepts the IStructuralComparable interface.

The interface has a single member, CompareTo, which determines whether the current collection object is less than, equal to, or greater than a second object in the sort order. The actual comparison of the members or elements in the current instance with those in a second object is performed by an IComparer interface implementation, which contains the definition of your custom comparison.

NoteNote:

The IStructuralComparable interface supports only structural comparisons for sorting or ordering. The IStructuralEquatable interface supports custom comparisons for structural equality.

The .NET Framework provides a default comparer, which is returned by the Comparer<T>.Default property.

The generic tuple classes (Tuple<T1>, Tuple<T1, T2>, Tuple<T1, T2, T3>, and so on) and the Array class provide explicit implementations of the IStructuralComparable interface. By casting (in C#) or converting (in Visual Basic) the current instance of an array or tuple to an IStructuralComparable interface value and providing your IComparer implementation as an argument to the CompareTo method, you can define a custom sort order for the array or collection. Most commonly, however, you do not call the CompareTo method directly. Instead, the CompareTo method is called by sorting methods such as Sort(Array, IComparer). In this case, you define your IComparer implementation and pass it as an argument to a sorting method or collection object's class constructor. The CompareTo method with your custom comparer is then called automatically whenever the collection is sorted.

Examples

The following example creates an array of Tuple<T1, T2, T3, T4, T5, T6> objects that contains population data for three U.S. cities from 1960 to 2000. The sextuple's first component is the city name. The remaining five components represent the population at ten-year intervals from 1960 to 2000.

The PopulationComparer class provides an IComparer implementation that allows the array of sextuples to be sorted by any one of its components. Two values are provided to the PopulationComparer class in its constructor: The position of the component that defines the sort order, and a Boolean value that indicates whether the tuple objects should be sorted in ascending or descending order.

The example then displays the elements in the array in unsorted order, sorts them by the third component (the population in 1970) and displays them, and then sorts them by the sixth component (the population in 2000) and displays them. Note that the example does not directly call the CompareTo method. The method is called implicitly by the Sort(Array, IComparer) method for each tuple object in the array.

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(ByVal component As Integer)
      Me.New(component, True)
   End Sub

   Public Sub New(ByVal component As Integer, ByVal 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(ByVal x As Object, ByVal 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 Demo(ByVal outputBlock As System.Windows.Controls.TextBlock)
      ' 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.
      outputBlock.Text &= "In unsorted order:" & vbCrLf
      For Each city In cities
         outputBlock.Text &= city.ToString() & vbCrLf
      Next
      outputBlock.Text &= vbCrLf

      Array.Sort(cities, New PopulationComparer(Of String, Integer, Integer, Integer, Integer, Integer)(3))

      ' Display array in sorted order.
      outputBlock.Text &= "Sorted by population in 1970:" & vbCrLf
      For Each city In cities
         outputBlock.Text &= city.ToString() & vbCrLf
      Next
      outputBlock.Text &= vbCrLf

      Array.Sort(cities, New PopulationComparer(Of String, Integer, Integer, Integer, Integer, Integer)(6))

      ' Display array in sorted order.
      outputBlock.Text &= "Sorted by population in 2000:" & vbCrLf
      For Each city In cities
         outputBlock.Text &= city.ToString() & vbCrLf
      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)
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 Demo(System.Windows.Controls.TextBlock outputBlock)
   {
      // 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.
      outputBlock.Text += "In unsorted order:" + "\n";
      foreach (var city in cities)
         outputBlock.Text += city.ToString() + "\n";
      outputBlock.Text += "\n";

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

      // Display array in sorted order.
      outputBlock.Text += "Sorted by population in 1970:" + "\n";
      foreach (var city in cities)
         outputBlock.Text += city.ToString() + "\n";
      outputBlock.Text += "\n";

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

      // Display array in sorted order.
      outputBlock.Text += "Sorted by population in 2000:" + "\n";
      foreach (var city in cities)
         outputBlock.Text += city.ToString() + "\n";
   }
}
// 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)

Version Information

Silverlight

Supported in: 5, 4

Platforms

For a list of the operating systems and browsers that are supported by Silverlight, see Supported Operating Systems and Browsers.