0Pricing
C# Academy · 강의

IComparable 구현

CompareTo로 자연스러운 정렬 순서를 정의합니다.

IComparable 구현은(는) CoddyKit의 무료 C# Academy 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 C# Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. C# Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

IComparable<T>를 사용한 정렬

IComparable<T>는 하나의 메서드인 CompareTo를 통해 형식의 자연스러운 순서를 정의합니다. 이를 구현하면 Array.Sort, List.Sort, 정렬된 컬렉션에서 해당 형식을 정렬할 수 있습니다.

CompareTo 규칙

CompareTo는 현재 인스턴스가 다른 인스턴스보다 작으면 음수, 같으면 0, 크면 양수를 반환합니다. 기반 값을 비교하면 이를 직접 구현할 수 있는 경우가 많습니다.

using System;

public struct Weight : IComparable<Weight>
{
    public int Grams;
    public Weight(int g) { Grams = g; }

    public int CompareTo(Weight other) => Grams.CompareTo(other.Grams);

    public override string ToString() => Grams + "g";
}

public class Program
{
    public static void Main()
    {
        Console.WriteLine(new Weight(100).CompareTo(new Weight(200)));
        Console.WriteLine(new Weight(200).CompareTo(new Weight(200)));
        Console.WriteLine(new Weight(300).CompareTo(new Weight(200)));
    }
}

List 정렬하기

형식이 비교 가능해지면 List<T>.Sort()가 추가 인수 없이 CompareTo를 사용하여 해당 형식의 순서를 정합니다.

using System;
using System.Collections.Generic;

public struct Weight : IComparable<Weight>
{
    public int Grams;
    public Weight(int g) { Grams = g; }
    public int CompareTo(Weight other) => Grams.CompareTo(other.Grams);
    public override string ToString() => Grams + "g";
}

public class Program
{
    public static void Main()
    {
        var list = new List<Weight> { new Weight(300), new Weight(100), new Weight(200) };
        list.Sort();
        Console.WriteLine(string.Join(", ", list));
    }
}

주요 필드를 기준으로 비교하기

클래스에서는 자연스러운 순서를 결정하는 필드를 선택하십시오. 여기서는 people을 나이를 기준으로 정렬하며, int.CompareTo에 위임합니다.

using System;
using System.Collections.Generic;

public class Person : IComparable<Person>
{
    public string Name;
    public int Age;
    public Person(string name, int age) { Name = name; Age = age; }
    public int CompareTo(Person other) => Age.CompareTo(other.Age);
    public override string ToString() => Name + "(" + Age + ")";
}

public class Program
{
    public static void Main()
    {
        var people = new List<Person> { new Person("Ann", 30), new Person("Bo", 20) };
        people.Sort();
        Console.WriteLine(string.Join(", ", people));
    }
}

여러 필드로 동률 깨기

주 키가 같으면 보조 필드를 비교하십시오. 첫 번째 비교를 수행하고, 그 결과가 0일 때만 다음 필드로 넘어갑니다.

using System;
using System.Collections.Generic;

public class Person : IComparable<Person>
{
    public string Name;
    public int Age;
    public Person(string name, int age) { Name = name; Age = age; }
    public int CompareTo(Person other)
    {
        int byAge = Age.CompareTo(other.Age);
        return byAge != 0 ? byAge : string.Compare(Name, other.Name, StringComparison.Ordinal);
    }
    public override string ToString() => Name + "(" + Age + ")";
}

public class Program
{
    public static void Main()
    {
        var people = new List<Person> { new Person("Zoe", 30), new Person("Ann", 30) };
        people.Sort();
        Console.WriteLine(string.Join(", ", people));
    }
}

배열 정렬하기

Array.Sort도 IComparable<T>에 의존합니다. 동일한 비교 논리가 배열, 목록, 정렬된 구조 모두에 사용됩니다.

using System;

public struct Score : IComparable<Score>
{
    public int Points;
    public Score(int p) { Points = p; }
    public int CompareTo(Score other) => Points.CompareTo(other.Points);
    public override string ToString() => Points.ToString();
}

public class Program
{
    public static void Main()
    {
        var scores = new[] { new Score(50), new Score(10), new Score(30) };
        Array.Sort(scores);
        Console.WriteLine(string.Join(", ", (object[])scores));
    }
}

내림차순

순서를 뒤집으려면 CompareTo의 피연산자를 서로 바꾸어 비교를 반전하십시오. 별도의 비교자 없이 높은 값부터 낮은 값으로 정렬하는 깔끔한 방법입니다.

using System;
using System.Collections.Generic;

public struct Score : IComparable<Score>
{
    public int Points;
    public Score(int p) { Points = p; }
    // Reversed: higher points come first
    public int CompareTo(Score other) => other.Points.CompareTo(Points);
    public override string ToString() => Points.ToString();
}

public class Program
{
    public static void Main()
    {
        var list = new List<Score> { new Score(10), new Score(50), new Score(30) };
        list.Sort();
        Console.WriteLine(string.Join(", ", list));
    }
}

비교 가능성과 같음 가능성을 함께 사용하기

CompareTo가 0을 반환하면 정렬 순서에서는 항목을 같은 것으로 봅니다. 정렬과 같음 판단이 일치하도록 이를 Equals와 일관되게 유지하십시오.

using System;

public struct Version : IComparable<Version>, IEquatable<Version>
{
    public int Major, Minor;
    public Version(int major, int minor) { Major = major; Minor = minor; }
    public int CompareTo(Version other)
    {
        int byMajor = Major.CompareTo(other.Major);
        return byMajor != 0 ? byMajor : Minor.CompareTo(other.Minor);
    }
    public bool Equals(Version other) => CompareTo(other) == 0;
    public override bool Equals(object obj) => obj is Version v && Equals(v);
    public override int GetHashCode() => HashCode.Combine(Major, Minor);
}

public class Program
{
    public static void Main()
    {
        Console.WriteLine(new Version(1, 2).CompareTo(new Version(1, 5)));
        Console.WriteLine(new Version(2, 0).Equals(new Version(2, 0)));
    }
}

LINQ OrderBy에서 비교 사용하기

제자리에서 정렬하지 않아도 LINQ OrderBy는 키 선택기를 통해 비교 가능한 형식을 사용할 수 있으며, 지연 방식으로 정렬된 뷰를 생성합니다.

using System;
using System.Collections.Generic;
using System.Linq;

public struct Weight : IComparable<Weight>
{
    public int Grams;
    public Weight(int g) { Grams = g; }
    public int CompareTo(Weight other) => Grams.CompareTo(other.Grams);
    public override string ToString() => Grams + "g";
}

public class Program
{
    public static void Main()
    {
        var items = new List<Weight> { new Weight(300), new Weight(100) };
        foreach (var w in items.OrderBy(x => x))
            Console.WriteLine(w);
    }
}

정렬 가능한 도메인 형식

IComparable<T>을 구현하면 도메인 개념을 전체 프레임워크에서 정렬할 수 있는 대상으로 만들 수 있습니다. 여기서는 작업을 우선순위로 정렬한 다음 이름으로 정렬합니다.

using System;
using System.Collections.Generic;

public class TaskItem : IComparable<TaskItem>
{
    public string Name;
    public int Priority;
    public TaskItem(string name, int priority) { Name = name; Priority = priority; }
    public int CompareTo(TaskItem other)
    {
        int byPriority = Priority.CompareTo(other.Priority);
        return byPriority != 0 ? byPriority : string.Compare(Name, other.Name, StringComparison.Ordinal);
    }
    public override string ToString() => Priority + ":" + Name;
}

public class Program
{
    public static void Main()
    {
        var tasks = new List<TaskItem>
        {
            new TaskItem("deploy", 2), new TaskItem("build", 1), new TaskItem("test", 1)
        };
        tasks.Sort();
        Console.WriteLine(string.Join(", ", tasks));
    }
}

직접 해 보기

여러 필드로 비교할 수 있는 형식을 만들고 해당 형식의 목록을 정렬해 보십시오. 추가 인수 없이 CompareTo에서 자연 순서가 결정됩니다.

using System;
using System.Collections.Generic;

public class Card : IComparable<Card>
{
    public int Rank;
    public string Suit;
    public Card(int rank, string suit) { Rank = rank; Suit = suit; }
    public int CompareTo(Card other)
    {
        int byRank = Rank.CompareTo(other.Rank);
        return byRank != 0 ? byRank : string.Compare(Suit, other.Suit, StringComparison.Ordinal);
    }
    public override string ToString() => Rank + Suit;
}

public class Program
{
    public static void Main()
    {
        var hand = new List<Card>
        {
            new Card(10, "H"), new Card(2, "S"), new Card(10, "C")
        };
        hand.Sort();
        Console.WriteLine(string.Join(", ", hand));
    }
}

빠른 확인

CompareTo 계약을 떠올려 보십시오.

복습

IComparable<T>은 CompareTo를 통해 자연 순서를 정의합니다.

  • 음수, 0, 양수는 각각 작음, 같음, 큼을 의미합니다.
  • List.Sort, Array.Sort 및 정렬된 컬렉션을 사용할 수 있게 합니다.
  • 값이 같으면 보조 필드를 비교하여 순서를 결정합니다.
  • CompareTo == 0이 Equals와 일관되도록 유지합니다.

자주 묻는 질문

“IComparable 구현” 강의는 무료인가요?

네 — “IComparable 구현” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 C# Academy 강의 전체를 잠금 해제할 수 있습니다. C# Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“IComparable 구현”에서 뭘 배우나요?

CompareTo로 자연스러운 정렬 순서를 정의합니다. 브라우저에서 직접 실행하는 실습 코드로 C# Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

C# Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 C# Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.

“IComparable 구현” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 C# Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 C# Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. IEquatable 구현
  2. GetHashCode 재정의
  3. IComparable 구현
  4. 사용자 지정 정렬을 위한 IComparer
← C# Academy(으)로 돌아가기