IStructuralComparable インターフェイス

定義

コレクション オブジェクトの構造比較をサポートします。

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

次の Tuple<T1,T2,T3,T4,T5,T6> 例では、1960 年から 2000 年までの 3 つの米国の都市の人口データを含む オブジェクトの配列を作成します。 sextuple の最初のコンポーネントは都市名です。 残りの 5 つの成分は、1960 年から 2000 年までの 10 年間の間隔での母集団を表します。

PopulationComparerクラスには、 IComparerにより、6つ組の配列をそのいずれかのコンポーネントでソートできるようにするIComparer実装を提供します。 PopulationComparerクラスのコンストラクターには 2 つの値があります。 並べ替え順序を定義するコンポーネントとタプルオブジェクトを昇順または降順で並べ替える必要があるかどうかを示すブール値の位置です。

次に、配列内の要素を並べ替えられていない順序で表示し、3 番目のコンポーネント (1970 年の母集団) で並べ替えて表示した後、6 番目のコンポーネント (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インターフェイスを使用すると、コレクション メンバーのカスタマイズされた比較を実装できます。 つまり、1 つのコレクション オブジェクトが 2 番目のコレクション オブジェクトと並べ替え順序で同じ位置に先行、フォロー、または発生する場合の意味を正確に定義できます。 その後、インターフェイスを受け入れる IStructuralComparable コレクション型でこの定義を使用することを指定できます。

インターフェイスには、 CompareTo現在のコレクション オブジェクトが並べ替え順序で 2 番目のオブジェクトより小さいか、等しいか、またはより大きいかを決定する 1 つのメンバーがあります。 現在のインスタンス内のメンバーまたは要素と 2 番目のオブジェクトのメンバーまたは要素の実際の比較は、カスタム比較の定義を IComparer 含むインターフェイス実装によって実行されます。

注意

インターフェイスでは IStructuralComparable 、並べ替えまたは順序付けの構造比較のみがサポートされます。 インターフェイスでは IStructuralEquatable 、構造の等価性に関するカスタム比較がサポートされています。

.NET Framework には、2 つの既定の比較子が用意されています。 1 つは プロパティによって StructuralComparisons.StructuralComparer 返され、もう 1 つは プロパティによって 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)

現在のコレクション オブジェクトの並べ替え順序での位置が、別のオブジェクトと比べて前か、後か、または同じかを判断します。

適用対象

こちらもご覧ください