[.net] IComparable <T> Vs를 사용하는 경우 IComparer <T>

구현해야하는 이러한 인터페이스를 파악하려고합니다. 둘 다 본질적으로 같은 일을합니다. 언제 다른 하나를 사용합니까?



답변

그럼 그들이하지 과 같은 일 IComparer<T>동안 두 개의 서로 다른 객체를 비교 할 수있는 유형에 구현되는 IComparable<T>같은 유형의 다른 인스턴스와 자신을 비교할 수있는 유형에 구현된다.

나는 IComparable<T>다른 인스턴스가 인스턴스와 어떤 관련이 있는지 알아야 할 때 사용하는 경향이 있습니다 this. 비교 IComparer<T>대상이 아니므로 컬렉션을 정렬하는 데 유용합니다 IComparer<T>.


답변

IComparable<T>클래스에 내재적 비교가있을 때 사용 합니다.

IComparer<T>클래스의 고유 비교 (있는 경우) 이외의 비교 방법을 원할 때 사용 합니다.


답변

엔티티에 따라 다릅니다. 예를 들어 “Student”와 같은 클래스의 경우 이름을 기반으로 IComparable을 사용하는 것이 좋습니다.

class Student : IComparable
{
    public string Name { get; set; }
    public int MathScore { get; set; }
    public int EnglishScore { get; set; }

    public int TotalScore
    {
        get
        {
            return this.MathScore + this.EnglishScore;
        }
    }

    public int CompareTo(object obj)
    {
        return CompareTo(obj as Student);
    }

    public int CompareTo(Student other)
    {
        if (other == null)
        {
            return 1;
        }
        return this.Name.CompareTo(other.Name);
    }
}

그런데 ‘A’선생님이 MathScore를 기준으로 학생들을 비교하고 싶다면 ‘B’선생님이 EnglishScore를 기준으로 학생들을 비교하고 싶어합니다. IComparer를 별도로 구현하는 것이 좋습니다. (전략 패턴과 비슷 함)

class CompareByMathScore : IComparer<Student>
{
    public int Compare(Student x, Student y)
    {
        if (x.MathScore > y.MathScore)
          return 1;
        if (x.MathScore < y.MathScore)
          return -1;
        else
          return 0;
    }
}


답변

그것은 모두 당신의 유형이 변경 가능한지 여부에 달려 있습니다. 변경 불가능한 유형 에서만 IComparable을 구현 해야 합니다 . IComparable을 구현하는 경우 ==,! =, <및> 연산자와 함께 Equals를 재정의해야합니다 (코드 분석 경고 CA1036 참조).

이 블로그 게시물 에서 Dave G를 인용합니다 .

그러나 정답은 개체가 변경 가능한 경우 IComparable 대신 IComparer를 구현하고 필요한 경우 IComparer의 인스턴스를 정렬 함수에 전달하는 것입니다.

IComparer는 해당 시점에서 정렬하는 데 사용되는 일회용 개체 일 뿐이므로 개체는 원하는 변경 가능한 의미를 가질 수 있습니다. 또한 Equals, GetHashCode 또는 == 사용을 요구하거나 제안하지도 않습니다. 원하는 방식으로 자유롭게 정의 할 수 있습니다.

마지막으로 다른 필드 또는 다른 규칙으로 정렬하기 위해 유형에 대해 여러 IComparer를 정의 할 수 있습니다. 이것은 하나의 정의에 집착하는 것보다 훨씬 더 유연합니다.

간단히 말해 , 값 유형에는 IComparable을 사용하고 참조 유형에는 IComparer를 사용하십시오.


답변

이야기를 통한 간단한 설명

고등학교 농구. 팀을위한 학교 운동장 선택입니다. 우리 팀에서 가장 키가 크고 / 최고 / 가장 빠른 사람들을 얻고 싶습니다. 어떡하죠?

IComparer 인터페이스 -두 사람을 개별적으로 비교

  • 이렇게하면 정렬 된 두 사람을 비교할 수 있습니다 ……. 기본적으로 그게 다입니다. Fred vs John ………. 인터페이스를 구현하는 구체적인 클래스에 그들을 던졌습니다. Compare(Fred, John)누가 더 나은지 뱉어냅니다.

IComparable은 어떻습니까? -다른 사람과 자신을 비교

최근에 FB에 가본 적이 있습니까? 다른 사람들이 멋진 일을하는 것을 볼 수 있습니다. 세계를 여행하고, 발명품을 만들고, 제가 그다지 멋지지 않은 일을하고 있습니다. 우리가하는 일은 IComparable 인터페이스를 사용하는 것입니다.

  • 현재 인스턴스 (자신)를 동일한 유형 (사람)의 다른 개체 (다른 사람)와 비교하고 있습니다.

비교 자 클래스는 어떻습니까?

Comparer 클래스는 IComparer 인터페이스를 구현하는 추상 기본 클래스입니다. 구체적으로 구현하려면이 클래스에서 파생해야합니다. 어쨌든 Microsoft는 IComparer 인터페이스를 구현하는 대신 Comparer 클래스를 사용하는 것이 좋습니다.

Comparer 클래스는 IComparer.Compare 메서드의 명시 적 인터페이스 구현과 개체의 기본 비교자를 가져 오는 Default 속성을 제공하므로 IComparer 인터페이스를 구현하는 대신 Comparer 클래스에서 파생하는 것이 좋습니다.

요약

  • IComparer-두 가지를 정렬하고 비교합니다.
  • IComparable-FB에서 다른 사람과 자신을 비교합니다.

이야기가 기억하는 데 도움이되기를 바랍니다.


답변

다른 사람들이 말했듯이 그들은 같은 일을하지 않습니다.

어쨌든 요즘 나는 IComparer를 사용하지 않는 경향이 있습니다. 내가 왜? 그 책임 (두 개체를 비교하는 데 사용되는 외부 엔터티)은 대부분의 LINQ 메서드 작동 방식과 유사하게 람다 식을 사용하여 훨씬 더 깔끔하게 처리 할 수 ​​있습니다. 비교할 객체를 인수로 취하고 bool을 반환하는 빠른 람다를 작성합니다. 개체가 고유 한 비교 작업을 정의하는 경우 대신 IComparable을 구현할 수 있습니다.


답변

IComparable은 개체를 다른 개체와 비교할 수 있다고 말합니다. IComparer는 두 항목을 비교할 수있는 개체입니다.