C#에서 컬렉션의 요소를 정렬하거나 객체 간 비교 로직이 필요할 때 IComparable과 IComparer 두 가지 인터페이스를 활용할 수 있습니다. 두 인터페이스는 이름이 비슷하지만 용도와 구현 방식에 분명한 차이가 있습니다. 이 글에서는 각 인터페이스의 개념과 예제 코드, 그리고 핵심 차이점까지 자세히 살펴보겠습니다.
C#의 IComparable 인터페이스란?
IComparable 인터페이스는 C#에서 요소를 정렬할 때 사용되며, 현재 인스턴스와 동일한 타입의 다른 객체를 비교하는 기능을 제공합니다. 즉, 특정 타입의 두 객체를 비교하는 방법을 클래스 내부에 직접 정의하는 것입니다.
IComparable 인터페이스를 구현할 때는 반드시 CompareTo() 메서드도 함께 구현해야 한다는 점을 기억하세요. 이 메서드는 비교 대상 객체를 매개변수로 받아, 현재 객체와의 상대적인 순서를 나타내는 정수 값을 반환합니다.
다음은 IComparable 인터페이스의 구현 예제입니다.
int IComparable.CompareTo(object ob) {
Vehicle v = (Vehicle)ob;
return String.Compare(this.make, v.make);
}
위 예제에서는 Vehicle 객체의 make(제조사) 문자열을 기준으로 두 객체를 비교하고 있습니다.
C#의 IComparer 인터페이스란?
IComparer 인터페이스는 두 객체를 비교하여 정렬하는 데 사용되며, 기본 정렬 방식 외에 추가적인 비교 기준이 필요할 때 유용합니다. IComparable이 클래스 자신의 기본 비교 규칙을 정의한다면, IComparer는 별도의 헬퍼 클래스를 통해 다양한 비교 기준을 유연하게 적용할 수 있습니다.
다음은 연도(year)를 오름차순으로 정렬하기 위한 IComparer 구현 예제입니다.
private class sortYearAscendingHelper : IComparer {
int IComparer.Compare(object ob1, object ob2) {
Vehicle v1 = (Vehicle)ob1;
Vehicle v2 = (Vehicle)ob2;
if (v1.year > v2.year)
return 1;
if (v1.year < v2.year)
return -1;
else
return 0;
}
}
이렇게 만든 비교자(Comparer)는 아래와 같이 IComparer 객체의 인스턴스를 반환하는 메서드를 통해 외부에서 손쉽게 사용할 수 있습니다.
public static IComparer sortYearAscending() {
return (IComparer)new sortYearAscendingHelper();
}
IComparable vs IComparer: 핵심 차이점 비교
| 구분 | IComparable | IComparer |
|---|---|---|
| 구현 위치 | 비교 대상 클래스 자체에 구현 | 별도의 헬퍼 클래스에 구현 |
| 필수 메서드 | CompareTo() | Compare() |
| 비교 방식 | 현재 인스턴스와 다른 객체 비교 | 두 개의 독립된 객체 비교 |
| 주요 용도 | 클래스의 기본 정렬 기준 정의 | 여러 가지 정렬 기준이 필요할 때 |
| 유연성 | 단일 비교 규칙만 가능 | 다양한 비교 규칙 동시 지원 |
마무리 정리
정리하면, IComparable은 클래스 내부에 기본 비교 규칙을 정의할 때 사용하고, IComparer는 원본 클래스 코드를 수정하지 않고도 여러 가지 정렬 기준을 외부에서 적용해야 할 때 사용합니다. 두 인터페이스를 상황에 맞게 적절히 활용하면 C#에서 더욱 유연하고 강력한 정렬 로직을 구현할 수 있습니다.