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 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- IEquatable 구현
- GetHashCode 재정의
- IComparable 구현
- 사용자 지정 정렬을 위한 IComparer