컬렉션 내에서 비교 및 정렬Comparisons and Sorts Within Collections

System.Collections 클래스는 제거할 요소 검색, 키-값 쌍의 값 반환 등 컬렉션 관리와 관련된 거의 모든 프로세스에서 비교를 수행합니다.The System.Collections classes perform comparisons in almost all the processes involved in managing collections, whether searching for the element to remove or returning the value of a key-and-value pair.

컬렉션은 일반적으로 같음 비교자 및/또는 순서 비교자를 사용합니다.Collections typically utilize an equality comparer and/or an ordering comparer. 비교에는 두 가지 구문이 사용됩니다.Two constructs are used for comparisons.

같음 확인Checking for equality

Contains, IndexOf, LastIndexOf, Remove 등의 메서드는 컬렉션 요소에 대해 같음 비교자를 사용합니다.Methods such as Contains, IndexOf, LastIndexOf, and Remove use an equality comparer for the collection elements. 제네릭 컬렉션의 경우 다음 지침에 따라 항목이 같은지를 비교합니다.If the collection is generic, than items are compared for equality according to the following guidelines:

또한 사전 컬렉션의 일부 생성자 오버로드는 키가 같은지를 비교하는 데 사용되는 IEqualityComparer<T> 구현을 허용합니다.In addition, Some constructor overloads for dictionary collections accept an IEqualityComparer<T> implementation, which is used to compare keys for equality. 예제를 보려면 Dictionary<TKey,TValue>.Dictionary<TKey,TValue> 생성자를 참조하세요.For an example, see the Dictionary<TKey,TValue>.Dictionary<TKey,TValue> constructor.

정렬 순서 결정Determining sort order

BinarySearchSort 와 같은 메서드는 컬렉션 요소에 대해 순서 비교자를 사용합니다.Methods such as BinarySearch and Sort use an ordering comparer for the collection elements. 컬렉션의 요소를 비교할 수도 있고 특정 요소와 지정된 값을 비교할 수도 있습니다.The comparisons can be between elements of the collection, or between an element and a specified value. 개체를 비교하는 경우에는 default comparerexplicit comparer의 개념이 적용됩니다.For comparing objects, there is the concept of a default comparer and an explicit comparer.

기본 비교자는 비교 대상 개체 중 하나 이상을 사용하여 IComparable 인터페이스를 구현합니다.The default comparer relies on at least one of the objects being compared to implement the IComparable interface. 사용되는 모든 클래스에 대해 IComparable 을 목록 컬렉션의 값 또는 사전 컬렉션의 키로 구현하는 것이 좋습니다.It is a good practice to implement IComparable on all classes are used as values in a list collection or as keys in a dictionary collection. 제네릭 컬렉션의 경우 다음 기준에 따라 같음 비교를 결정합니다.For a generic collection, equality comparison is determined according to the following:

  • T 형식이 System.IComparable<T> 제네릭 인터페이스를 구현하는 경우 기본 비교자는 해당 인터페이스의 IComparable<T>.CompareTo(T) 메서드입니다.If type T implements the System.IComparable<T> generic interface, then the default comparer is the IComparable<T>.CompareTo(T) method of that interface

  • T 형식이 제네릭이 아닌 System.IComparable 인터페이스를 구현하는 경우 기본 비교자는 해당 인터페이스의 IComparable.CompareTo(Object) 메서드입니다.If type T implements the non-generic System.IComparable interface, then the default comparer is the IComparable.CompareTo(Object) method of that interface.

  • T 형식이 두 인터페이스를 모두 구현하지 않는 경우에는 기본 비교자가 없으며 비교자 또는 비교 대리자를 명시적으로 제공해야 합니다.If type T doesn’t implement either interface, then there is no default comparer, and a comparer or comparison delegate must be provided explicitly.

명시적 비교를 제공할 수 있도록 일부 메서드는 매개 변수로 IComparer 구현을 허용합니다.To provide explicit comparisons, some methods accept an IComparer implementation as a parameter. 예를 들어 List<T>.Sort 메서드는 System.Collections.Generic.IComparer<T> 구현을 허용합니다.For example, the List<T>.Sort method accepts an System.Collections.Generic.IComparer<T> implementation.

시스템의 현재 문화권 설정은 컬렉션 내의 비교와 정렬에 영향을 줄 수 있습니다.The current culture setting of the system can affect the comparisons and sorts within a collection. 기본적으로 Collections 클래스의 비교 및 정렬은 문화권을 구분합니다.By default, the comparisons and sorts in the Collections classes are culture-sensitive. 문화권 설정을 무시하고 동일한 비교 및 정렬 결과가 반환되도록 하려면 InvariantCulture 를 허용하는 멤버 오버로드를 포함하여 CultureInfo를 사용합니다.To ignore the culture setting and therefore obtain consistent comparison and sorting results, use the InvariantCulture with member overloads that accept a CultureInfo. 자세한 내용은 Performing Culture-Insensitive String Operations in CollectionsPerforming Culture-Insensitive String Operations in Arrays를 참조하세요.For more information, see Performing Culture-Insensitive String Operations in Collections and Performing Culture-Insensitive String Operations in Arrays.

같음 및 정렬 예제Equality and sort example

다음 코드에서는 간단한 비즈니스 개체에 대한 IEquatable<T>IComparable<T> 의 구현을 보여 줍니다.The following code demonstrates an implementation of IEquatable<T> and IComparable<T> on a simple business object. 또한 개체를 목록에 저장하고 정렬할 때 Sort() 메서드를 호출하면 Part 형식에 대해 기본 비교자가 사용되며, 무명 메서드를 사용하여 Sort(Comparison<T>) 메서드가 구현됩니다.In addition, when the object is stored in a list and sorted, you will see that calling the Sort() method results in the use of the default comparer for the Part type, and the Sort(Comparison<T>) method implemented by using an anonymous method.

using System;
using System.Collections.Generic;
// Simple business object. A PartId is used to identify the type of part 
// but the part name can change. 
public class Part : IEquatable<Part> , IComparable<Part>
{
    public string PartName { get; set; }

    public int PartId { get; set; }

    public override string ToString()
    {
        return "ID: " + PartId + "   Name: " + PartName;
    }
    public override bool Equals(object obj)
    {
        if (obj == null) return false;
        Part objAsPart = obj as Part;
        if (objAsPart == null) return false;
        else return Equals(objAsPart);
    }
    public int SortByNameAscending(string name1, string name2)
    {
        
        return name1.CompareTo(name2);
    }

    // Default comparer for Part type.
    public int CompareTo(Part comparePart)
    {
          // A null value means that this object is greater.
        if (comparePart == null)
            return 1;
            
        else
            return this.PartId.CompareTo(comparePart.PartId);
    }
    public override int GetHashCode()
    {
        return PartId;
    }
    public bool Equals(Part other)
    {
        if (other == null) return false;
        return (this.PartId.Equals(other.PartId));
    }
    // Should also override == and != operators.

}
public class Example
{
    public static void Main()
    {
        // Create a list of parts.
        List<Part> parts = new List<Part>();

        // Add parts to the list.
        parts.Add(new Part() { PartName = "regular seat", PartId = 1434 });
        parts.Add(new Part() { PartName= "crank arm", PartId = 1234 });
        parts.Add(new Part() { PartName = "shift lever", PartId = 1634 }); ;
        // Name intentionally left null.
        parts.Add(new Part() {  PartId = 1334 });
        parts.Add(new Part() { PartName = "banana seat", PartId = 1444 });
        parts.Add(new Part() { PartName = "cassette", PartId = 1534 });
       

        // Write out the parts in the list. This will call the overridden 
        // ToString method in the Part class.
        Console.WriteLine("\nBefore sort:");
        foreach (Part aPart in parts)
        {
            Console.WriteLine(aPart);
        }


        // Call Sort on the list. This will use the 
        // default comparer, which is the Compare method 
        // implemented on Part.
        parts.Sort();


        Console.WriteLine("\nAfter sort by part number:");
        foreach (Part aPart in parts)
        {
            Console.WriteLine(aPart);
        }
       
        // This shows calling the Sort(Comparison(T) overload using 
        // an anonymous method for the Comparison delegate. 
        // This method treats null as the lesser of two values.
        parts.Sort(delegate(Part x, Part y)
        {
            if (x.PartName == null && y.PartName == null) return 0;
            else if (x.PartName == null) return -1;
            else if (y.PartName == null) return 1;
            else return x.PartName.CompareTo(y.PartName);
        });

        Console.WriteLine("\nAfter sort by name:");
        foreach (Part aPart in parts)
        {
            Console.WriteLine(aPart);
        }
       
        /*
       
            Before sort:
		ID: 1434   Name: regular seat
		ID: 1234   Name: crank arm
		ID: 1634   Name: shift lever
		ID: 1334   Name:
		ID: 1444   Name: banana seat
		ID: 1534   Name: cassette

	    After sort by part number:
		ID: 1234   Name: crank arm
		ID: 1334   Name:
		ID: 1434   Name: regular seat
		ID: 1444   Name: banana seat
		ID: 1534   Name: cassette
		ID: 1634   Name: shift lever

	    After sort by name:
		ID: 1334   Name:
		ID: 1444   Name: banana seat
		ID: 1534   Name: cassette
		ID: 1234   Name: crank arm
		ID: 1434   Name: regular seat
		ID: 1634   Name: shift lever

         */

    }
}
Imports System.Collections.Generic
' Simple business object. A PartId is used to identify the type of part 
' but the part name can change. 
Public Class Part
    Implements IEquatable(Of Part)
    Implements IComparable(Of Part)
    Public Property PartName() As String
        Get
            Return m_PartName
        End Get
        Set(value As String)
            m_PartName = Value
        End Set
    End Property
    Private m_PartName As String

    Public Property PartId() As Integer
        Get
            Return m_PartId
        End Get
        Set(value As Integer)
            m_PartId = Value
        End Set
    End Property
    Private m_PartId As Integer

    Public Overrides Function ToString() As String
        Return "ID: " & PartId & "   Name: " & PartName
    End Function

    Public Overrides Function Equals(obj As Object) As Boolean
        If obj Is Nothing Then
            Return False
        End If
        Dim objAsPart As Part = TryCast(obj, Part)
        If objAsPart Is Nothing Then
            Return False
        Else
            Return Equals(objAsPart)
        End If
    End Function

    Public Function SortByNameAscending(name1 As String, name2 As String) As Integer

        Return name1.CompareTo(name2)
    End Function

    ' Default comparer for Part.
    Public Function CompareTo(comparePart As Part) As Integer _
            Implements IComparable(Of ListSortVB.Part).CompareTo
        ' A null value means that this object is greater.
        If comparePart Is Nothing Then
            Return 1
        Else

            Return Me.PartId.CompareTo(comparePart.PartId)
        End If
    End Function
    Public Overrides Function GetHashCode() As Integer
        Return PartId
    End Function
    Public Overloads Function Equals(other As Part) As Boolean Implements IEquatable(Of ListSortVB.Part).Equals
        If other Is Nothing Then
            Return False
        End If
        Return (Me.PartId.Equals(other.PartId))
    End Function
    ' Should also override == and != operators.

End Class
Public Class Example
    Public Shared Sub Main()
        ' Create a list of parts.
        Dim parts As New List(Of Part)()

        ' Add parts to the list.
        parts.Add(New Part() With { _
             .PartName = "regular seat", _
             .PartId = 1434 _
        })
        parts.Add(New Part() With { _
             .PartName = "crank arm", _
             .PartId = 1234 _
        })
        parts.Add(New Part() With { _
             .PartName = "shift lever", _
             .PartId = 1634 _
        })


        ' Name intentionally left null.
        parts.Add(New Part() With { _
             .PartId = 1334 _
        })
        parts.Add(New Part() With { _
             .PartName = "banana seat", _
             .PartId = 1444 _
        })
        parts.Add(New Part() With { _
             .PartName = "cassette", _
             .PartId = 1534 _
        })


        ' Write out the parts in the list. This will call the overridden 
        ' ToString method in the Part class.
        Console.WriteLine(vbLf & "Before sort:")
        For Each aPart As Part In parts
            Console.WriteLine(aPart)
        Next


        ' Call Sort on the list. This will use the 
        ' default comparer, which is the Compare method 
        ' implemented on Part.
        parts.Sort()


        Console.WriteLine(vbLf & "After sort by part number:")
        For Each aPart As Part In parts
            Console.WriteLine(aPart)
        Next

        ' This shows calling the Sort(Comparison(T) overload using 
        ' an anonymous delegate method. 
        ' This method treats null as the lesser of two values.
        parts.Sort(Function(x As Part, y As Part)
                             If x.PartName Is Nothing AndAlso y.PartName Is Nothing Then
                                 Return 0
                             ElseIf x.PartName Is Nothing Then
                                 Return -1
                             ElseIf y.PartName Is Nothing Then
                                 Return 1
                             Else
                                 Return x.PartName.CompareTo(y.PartName)
                             End If
                         End Function)
        

        Console.WriteLine(vbLf & "After sort by name:")
        For Each aPart As Part In parts
            Console.WriteLine(aPart)
        Next

        '
        '        
        '            Before sort:
        '            ID: 1434   Name: regular seat
        '            ID: 1234   Name: crank arm
        '            ID: 1634   Name: shift lever
        '            ID: 1334   Name:
        '            ID: 1444   Name: banana seat
        '            ID: 1534   Name: cassette
        '
        '            After sort by part number:
        '            ID: 1234   Name: crank arm
        '            ID: 1334   Name:
        '            ID: 1434   Name: regular seat
        '            ID: 1444   Name: banana seat
        '            ID: 1534   Name: cassette
        '            ID: 1634   Name: shift lever
        '
        '            After sort by name:
        '            ID: 1334   Name:
        '            ID: 1444   Name: banana seat
        '            ID: 1534   Name: cassette
        '            ID: 1234   Name: crank arm
        '            ID: 1434   Name: regular seat
        '            ID: 1634   Name: shift lever

    End Sub
End Class

참고 항목See Also

IComparer
IEquatable<T>
IComparer<T>
IComparable
IComparable<T>