개념공부/자투리 지식

IComparable<T>

Cadi 2025. 7. 23. 02:05

목차

    01.  문제 상황

     

    기본형인 int,string 등은 List에 넣었을 때 Sort를 사용하면 자연스럽게 되지만 ,

    직접 만든 Class들은 List 안에서 정렬이 되지 않는 문제가 있었다. 

    이는 '정렬의 기준'이 없어서 발생한 문제이고, '정렬의 기준'을 잡아주어야 한다.

    public class ItemTradeData :IComparable<ItemTradeData>
    {
        public ItemType itemType;
        public int price;
        [FormerlySerializedAs("quantity")] public int amount;
        public int demand;
        public int supply;
        public ItemTradeData()
        {
        }
        public ItemTradeData(ItemType itemType, int price,int amount, int demand = 0, int supply = 0)
        {
            this.itemType = itemType;
            this.price = price;
            this.amount = amount;
            this.demand = demand;
            this.supply = supply;
        }
        public int CompareTo(ItemTradeData other)
        {
            // itemType의 이름을 기준으로 정렬 (가나다순/사전순)
            return this.itemType.ToString().CompareTo(other.itemType.ToString());
        }
    }

     

    IComparable<T>이 '비교 기준'을 알려주는 인터페이스다.

     

    02. 핵심 개념

     

    public interface IComparable<T>
    {
        int CompareTo(T other);
    }

     

    T 타입과 자기 자신을 비교하는 방식이다. 리턴 값은 int로 의미는 다음과 같다.

     

    • 음수: this < other
    • 0: this == other
    • 양수: this > other

     

    03. 내부 구조

     

    List<T>.Sort()는 내부적으로 QuickSort와 같은 정렬 알고리즘을 사용한다.

    정렬 중에는 필연적으로 요소들간의 비교가 행해지는데, 이 때 CompareTo()가 호출된다. 

     

    예 ) 

    item1.CompareTo(item2) → 음수 → item1 앞에
    item3.CompareTo(item2) → 양수 → item3 뒤에

     

     

     

    04. 추가 팁

     

    Icomparable<T>

    IComparable<T>가 객체 스스로 비교 기준을 가졌다면, 

    IComparer<T>는 외부에서 비교 기준을 만들어주는 방식이다.

     

    public class SortByName : IComparer<Item>
    {
        public int Compare(Item x, Item y)
        {
            return x.name.CompareTo(y.name); // 이름 기준 정렬
        }
    }
    
    // 사용
    items.Sort(new SortByName());
     

     

    실수 방지 팁

    CompareTo()에서는 null 체크를 먼저 해 주는 것이 좋다.

    if (other == null) return 1; // null보다 무조건 큼