IComparable과 IEquatable 인터페이스의 차이점은 무엇입니까?


답변:


188

IEquatable 두 개체가 같은지 테스트합니다.

IComparable 비교되는 개체에 전체 순서를 적용합니다.

예를 들어, IEquatable5가 7과 같지 않다고 IComparable말하면 5가 7보다 먼저옵니다.



10

Greg D의 답변 외에도 :

부분적 순서가 의미가있는 클래스를 구현 IComparable하지 않고 구현할 수 IEquatable있으며 소비자 CompareTo()가 0을 반환 하기 때문에 소비자가 추론하기를 원할 경우 객체가 동일하다는 것을 의미하지는 않습니다 (정렬 목적 이외의 용도로).


10
개체가 IComparable제대로 구현되는 것보다 특수한 경우 비교 자처럼 ​​들립니다 . 평등을 의미 CompareTo(…) == 0하지 않는 의미 있는 예를 생각해 낼 수 있습니까 ? 나는 확실히 할 수 없다. 사실, 인터페이스 계약 (MSDN에 따라) CompareTo(…) == 0 동등성 을 의미합니다. 당신은 특별한 사용으로 이러한 경우에, 솔직하게 말하면 Comparator객체를 수행 하지 구현 IComparable.
Konrad Rudolph

2
@Konrad-유형이 IEquatable을 구현하지 않으며 (분명히 작성자가 동등성 테스트를 포함하고 싶지 않음) CompareTo 결과가 동등성을 평가 하지 않고 정렬에 사용된다는 몇 가지주의 사항을 표시했습니다 . 또한 어떤 평등이 관련되어 있는지에 대한 질문을 받게됩니다 (참조, 값, "임의"속성 무시-IComparable의 목적을 위해 길이가 500 페이지 인 파란색 책은 길이가 500 페이지 인 빨간색 책과 "동일"할 수 있음).
Damien_The_Unbeliever 2010 년

4
당신의 마지막 문장은 틀렸고, 이것은 제가 지적하고 싶은 특별한 실수 IComparable입니다. 여기서는 완전히 부적절합니다. 당신이 가진 것은 오직 하나의 특별한 상황에서만 적용되는 매우 특별한 순서입니다. 그러한 상황에서는 장군을 구현하는 IComparable것이 잘못되었습니다. 이것이 IComparer거기에있는 것입니다. 예를 들어, 사람을 의미있게 주문할 수 없습니다. 그러나 급여, 신발 사이즈, 주근깨 수 또는 체중에 따라 주문할 있습니다. 따라서 우리는 IComparer이러한 모든 경우에 대해 다른를 구현 합니다.
Konrad Rudolph

2
@Konrad Rudolph : 특정 시간에 "무언가"를 수행해야하는 "ScheduledEvent"클래스는 어떻습니까? 유형의 의미론은 조치가 발생해야하는시기를 기반으로하는 매우 강력한 자연적 의미 순서를 의미하지만 동시에 다른 이벤트가 발생하기 쉽게 가질 수 있습니다. 수동으로 지정된 IComparer를 사용해야 할 수도 있지만 비교기가 클래스에 내장되어 있으면 더 편리 할 것입니다.
supercat

4
@supercat 편의성은 중요하지만 모든 것이 아닙니다. 정확성 (논리적 일관성과 마찬가지로)이 더 중요하며 정적 유형 시스템은 이러한 논리적 일관성을 확인하는 중요한 도구입니다. 구현하는 인터페이스의 문서화 된 계약을 위반함으로써 형식 시스템을 파괴하는 것입니다. 입니다 하지 좋은 생각, 나는 그것을 추천하지 않을 것입니다. 이러한 상황에서는 외부 비교자를 사용하십시오.
Konrad Rudolph

7

IEquatableMSDN 페이지에 명시된대로 :

IComparable 인터페이스는 CompareTo구현 유형의 인스턴스 정렬 순서를 결정 하는 메서드를 정의합니다 . IEquatable 인터페이스는 Equals구현 유형의 인스턴스가 같음을 결정 하는 메서드를 정의합니다 .

EqualsCompareTo


2

IComparable <T> 객체를 정렬하거나 정렬하는 데 사용할 수있는 유형별 비교 방법을 정의합니다.

IEquatable <T> 평등을 결정하기 위해 구현하는 데 사용할 수있는 일반화 된 방법을 정의합니다.


Person 클래스가 있다고 가정 해 보겠습니다.

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

Person p1 = new Person() { Name = "Person 1", Age = 34 };
Person p2 = new Person() { Name = "Person 2", Age = 31 };
Person p3 = new Person() { Name = "Person 3", Age = 33 };
Person p4 = new Person() { Name = "Person 4", Age = 26 };

List<Person> people = new List<Person> { p1, p2, p3, p4 };

이러한 개체를 정렬하려면을 사용할 수 있습니다 people.Sort();.

그러나 이것은 예외를 던질 것입니다.

여기에 이미지 설명 입력

프레임 워크는 이러한 개체를 정렬하는 방법을 모릅니다. 구현 IComparable인터페이스 를 정렬하는 방법을 알려줄 필요가 있습니다.

public class Person : IComparable
{
    public string Name { get; set; }
    public int Age { get; set; }

    public int CompareTo(object obj)
    {
        Person otherPerson = obj as Person;
        if (otherPerson == null)
        {
            throw new ArgumentNullException();
        }
        else
        {
            return Age.CompareTo(otherPerson.Age);
        }
    }
}

Sort()메서드를 사용 하여 배열을 적절하게 정렬합니다 .


다음으로 두 개체를 비교하려면 Equals()방법 을 사용할 수 있습니다 .

var newPerson = new Person() { Name = "Person 1", Age = 34 };
var newPersonIsPerson1 = newPerson.Equals(p1);

falseEquals메서드가 두 개체를 비교하는 방법을 모르기 때문에 반환 됩니다. 따라서 IEquatable인터페이스 를 구현 하고 프레임 워크에 비교 방법을 알려야합니다. 이전 예제를 확장하면 다음과 같이 보일 것입니다.

public class Person : IComparable, IEquatable<Person>
{
    //Some code hidden

    public bool Equals(Person other)
    {
        if (Age == other.Age && Name == other.Name)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}

1
이 훌륭한 설명에 감사드립니다. 질문 : 왜 않는 IEquatable일반적인를 사용 <Person>하고 IComparable하지 않는 이유는 무엇입니까?
veuncent
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.