IStructuralComparable IStructuralComparable IStructuralComparable IStructuralComparable Interface

定义

支持集合对象的结构比较。Supports the structural comparison of collection objects.

public interface class IStructuralComparable
public interface IStructuralComparable
type IStructuralComparable = interface
Public Interface IStructuralComparable
派生

示例

下面的示例创建一个Tuple<T1,T2,T3,T4,T5,T6>对象数组, 其中包含三个美国城市的人口数据 (从1960到 2000)。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. 剩余的五个组件表示从1960到2000的10年间隔的人口。The remaining five components represent the population at ten-year intervals from 1960 to 2000.

类提供一个IComparer实现, 该实现允许 sextuples 的数组按其任何一个组件进行排序。 PopulationComparerThe PopulationComparer class provides an IComparer implementation that allows the array of sextuples to be sorted by any one of its components. 向类中的PopulationComparer构造函数提供了两个值: 定义排序顺序的组件的位置, 以及一个指示是否应按升序或降序对元组对象进行排序的布尔值。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.

然后, 该示例以未排序的顺序显示数组中的元素, 按第三个组件 (1970 中的人口) 对它们进行排序并显示它们, 然后将它们按第六个组件 (由2000填充) 进行排序并显示它们。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. 请注意, 该示例不会直接调用CompareTo方法。Note that the example does not directly call the CompareTo method. 此方法由Sort(Array, IComparer)数组中每个元组对象的方法隐式调用。The method is called implicitly by the Sort(Array, IComparer) method for each tuple object in the array.

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接口使您能够实现集合成员的自定义比较。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. 然后, 你可以指定将此定义用于接受IStructuralComparable接口的集合类型。You can then specify that this definition be used with a collection type that accepts the IStructuralComparable interface.

此接口具有一个成员, CompareTo该成员确定当前集合对象在排序顺序中是小于、等于还是大于第二个对象。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. 当前实例中的成员或元素与第二个对象中的成员或元素的实际比较是通过IComparer接口实现执行的, 后者包含自定义比较的定义。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.

备注

IStructuralComparable接口仅支持用于排序或排序的结构比较。The IStructuralComparable interface supports only structural comparisons for sorting or ordering. IStructuralEquatable接口支持结构相等性的自定义比较。The IStructuralEquatable interface supports custom comparisons for structural equality.

.NET Framework 提供了两个默认比较器。The .NET Framework provides two default comparers. 一个由StructuralComparisons.StructuralComparer属性返回, 另一个由Comparer<T>.Default属性返回。One is returned by the StructuralComparisons.StructuralComparer property; the other is returned by the Comparer<T>.Default property.

泛型元组类 (Tuple<T1>Tuple<T1,T2>Tuple<T1,T2,T3>等) IStructuralComparableArray类提供接口的显式实现。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. 通过强制转换 ( C#在中) 或将数组或元组的当前实例 Visual Basic 转换为IStructuralComparable接口IComparer值, 并将实现作为参数提供给CompareTo方法, 可以定义自定义排序顺序数组或集合。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. 不过, 在大多数情况下不CompareTo会直接调用方法。However, you do not call the CompareTo method directly in most cases. 相反, CompareTo方法通过对Sort(Array, IComparer)等方法进行调用。Instead, the CompareTo method is called by sorting methods such as Sort(Array, IComparer). 在这种情况下, 需要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. 然后CompareTo , 在对集合进行排序时, 将自动调用具有自定义比较器的方法。The CompareTo method with your custom comparer is then called automatically whenever the collection is sorted.

方法

CompareTo(Object, IComparer) CompareTo(Object, IComparer) CompareTo(Object, IComparer) CompareTo(Object, IComparer)

确定当前集合对象在排序顺序中的位置是位于另一个对象之前、之后还是与其位置相同。Determines whether the current collection object precedes, occurs in the same position as, or follows another object in the sort order.

适用于

另请参阅