IStructuralComparable 인터페이스

정의

컬렉션 개체의 구조 비교를 지원합니다.

public interface class IStructuralComparable
public interface IStructuralComparable
type IStructuralComparable = interface
Public Interface IStructuralComparable
파생

예제

다음 예제에서는 1960년부터 2000년까지 미국 3개 도시에 대한 인구 데이터를 포함하는 개체 배열 Tuple<T1,T2,T3,T4,T5,T6> 을 만듭니다. sextuple의 첫 번째 구성 요소는 도시 이름입니다. 나머지 5개 구성 요소는 1960년부터 2000년까지 10년 간격으로 모집단을 나타냅니다.

클래스는 PopulationComparer 구성 요소 중 하나를 기준으로 sextuples 배열을 정렬할 수 있는 구현을 제공합니다 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#에서) 또는 배열 또는 튜플 IStructuralComparable 의 현재 인스턴스를 인터페이스 값으로 변환하거나 메서드에 대한 인수로 구현을 IComparer 제공하면 배열 또는 컬렉션에 대한 사용자 지정 정렬 순서를 정의할 CompareTo 수 있습니다. 그러나 대부분의 경우 메서드를 CompareTo 직접 호출하지는 않습니다. 대신 와 CompareTo 같은 Sort(Array, IComparer)메서드를 정렬하여 메서드를 호출합니다. 이 경우 구현을 IComparer 정의하고 정렬 메서드 또는 컬렉션 개체의 클래스 생성자에 인수로 전달합니다. CompareTo 사용자 지정 비교자를 사용하는 메서드는 컬렉션이 정렬될 때마다 자동으로 호출됩니다.

메서드

CompareTo(Object, IComparer)

정렬 순서에서 현재 컬렉션 개체의 위치가 다른 개체보다 앞인지, 뒤인지 또는 동일한지를 확인합니다.

적용 대상

추가 정보