Полное руководство по языку программирования С# 14 и платформе .NET 10 / Интерфейсы

Сортировка объектов. Интерфейс IComparable

Начальный ⏱ 4 мин чтения 👁 2 🕓 обновлено 11.08.2026

Большинство встроенных в .NET классов коллекций и массивы поддерживают сортировку. С помощью одного метода, который, как правило, называется Sort() можно сразу отсортировать по возрастанию весь набор данных. Например:


int[] numbers = new int[] { 97, 45, 32, 65, 83, 23, 15 };
Array.Sort(numbers);
foreach (int n in numbers)
    Console.WriteLine(n);
// 15 23 32 45 65 83 97

Однако метод Sort по умолчанию работает только для наборов примитивных типов, как int или string. Для сортировки наборов сложных объектов применяется интерфейс IComparable. Он имеет всего один метод:


public interface IComparable
{
    int CompareTo(object? o);
}

Метод CompareTo предназначен для сравнения текущего объекта с объектом, который передается в качестве параметра object? o. На выходе он возвращает целое число, которое может иметь одно из трех значений:

  • Меньше нуля. Значит, текущий объект должен находиться перед объектом, который передается в качестве параметра

  • Равен нулю. Значит, оба объекта равны

  • Больше нуля. Значит, текущий объект должен находиться после объекта, передаваемого в качестве параметра

Например, имеется класс Person:


class Person : IComparable
{
    public string Name { get;}
    public int Age { get; set; }
    public Person(string name, int age)
    {
        Name = name; Age = age;
    }
    public int CompareTo(object? o)
    {
        if(o is Person person) return Name.CompareTo(person.Name);
        else throw new ArgumentException("Некорректное значение параметра");
    }
}

Здесь в качестве критерия сравнения выбрано свойство Name объекта Person. Поэтому при сравнении здесь фактически идет сравнение значения свойства Name текущего объекта и свойства Name объекта, переданного через параметр. Если вдруг объект не удастся привести к типу Person, то выбрасывается исключение.

Применение:


var tom = new Person("Tom", 37);
var bob = new Person("Bob", 41);
var sam = new Person("Sam", 25);

Person[] people = { tom, bob, sam};
Array.Sort(people);

foreach (Person person in people)
{
    Console.WriteLine($"{person.Name} - {person.Age}");
}

И в данном случае мы получим следующий консольный вывод:

Bob - 41
Sam - 25
Tom - 37

Интерфейс IComparable имеет обобщенную версию, поэтому мы могли бы сократить и упростить его применение в классе Person:


class Person : IComparable<Person>
{
    public string Name { get;}
    public int Age { get; set; }
    public Person(string name, int age)
    {
        Name = name; Age = age;
    }
    public int CompareTo(Person? person)
    {
        if(person is null) throw new ArgumentException("Некорректное значение параметра");
        return Name.CompareTo(person.Name);
    }
}

Аналогичным образом мы можем сравнивать по возрасту:


class Person : IComparable<Person>
{
    public string Name { get;}
    public int Age { get; set; }
    public Person(string name, int age)
    {
        Name = name; Age = age;
    }
    public int CompareTo(Person? person)
    {
        if(person is null) throw new ArgumentException("Некорректное значение параметра");
        return Age - person.Age;
    }
}

Применение компаратора

Кроме интерфейса IComparable платформа .NET также предоставляет интерфейс IComparer:


public interface IComparer<in T>
{
	int Compare(T? x, T? y);
}

Метод Compare предназначен для сравнения двух объектов o1 и o2. Он также возвращает три значения, в зависимости от результата сравнения: если первый объект больше второго, то возвращается число больше 0, если меньше - то число меньше нуля; если оба объекта равны, возвращается ноль.

Создадим компаратор объектов Person. Пусть он сравнивает объекты в зависимости от длины строки - значения свойства Name:


class PeopleComparer : IComparer<Person>
{
    public int Compare(Person? p1, Person? p2)
    {
        if(p1 is null || p2 is null) 
            throw new ArgumentException("Некорректное значение параметра");
        return p1.Name.Length - p2.Name.Length;
    }
}

class Person
{
    public string Name { get;}
    public int Age { get; set; }
    public Person(string name, int age)
    {
        Name = name; Age = age;
    }
}

В данном случае используется обобщенная версия интерфейса IComparer, чтобы не делать излишних преобразований типов. Применение компаратора:


var alice = new Person("Alice", 41);
var tom = new Person("Tom", 37);
var kate = new Person("Kate", 25);

Person[] people = { alice, tom, kate};
Array.Sort(people, new PeopleComparer());

foreach (Person person in people)
{
    Console.WriteLine($"{person.Name} - {person.Age}");
}

Объект компаратора указывается в качестве второго параметра метода Array.Sort(). При этом не важно, реализует ли класс Person интерфейс IComparable или нет. Правила сортировки, установленные компаратором, будут иметь больший приоритет. В начале будут идти объекты Person, у которых имена меньше, а в конце - у которых имена длиннее:

Tom - 37
Kate - 25
Alice - 41

Проверь себя

📋 Тест по теме «Сортировка объектов. Интерфейс IComparable» Тест по теме

Практические задания

Лёгкое Ручная проверка Заполните пропуск в коде (1)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

int[] _____ = new int[] { 97, 45, 32, 65, 83, 23, 15 };
Array.Sort(numbers);
foreach (int n in numbers)
    Console.WriteLine(n);
// 15 23 32 45 65 83 97
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (2)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

public interface _____
{
    int CompareTo(object? o);
}
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (3)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

class Person : IComparable
{
    public string _____ { get;}
    public int Age { get; set; }
    public Person(string name, int age)
    {
        Name = name; Age = age;
    }
    public int CompareTo(object? o)
    {
        if(o is Person person) return Name.CompareTo(person.Name);
        else throw new ArgumentException("Некорректное значение параметра");
    }
}
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (4)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

var tom = new Person("_____", 37);
var bob = new Person("Bob", 41);
var sam = new Person("Sam", 25);

Person[] people = { tom, bob, sam};
Array.Sort(people);

foreach (Person person in people)
{
    Console.WriteLine($"{person.Name} - {person.Age}");
}
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (5)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

class Person : IComparable<Person>
{
    public string Name { _____;}
    public int Age { get; set; }
    public Person(string name, int age)
    {
        Name = name; Age = age;
    }
    public int CompareTo(Person? person)
    {
        if(person is null) throw new ArgumentException("Некорректное значение параметра");
        return Name.CompareTo(person.Name);
    }
}
Войдите, чтобы отправить решение
Среднее Ручная проверка Восстановите код по памяти (1)
+20 XP

В этом фрагменте кода урока пропущены два ключевых элемента. Впишите оба пропущенных значения через запятую в порядке появления (например: x, 5).

int[] numbers = new int[] { 97, 45, 32, 65, 83, _____, 15 };
Array._____(numbers);
foreach (int n in numbers)
    Console.WriteLine(n);
// 15 23 32 45 65 83 97
Войдите, чтобы отправить решение
Среднее Ручная проверка Восстановите код по памяти (2)
+20 XP

В этом фрагменте кода урока пропущены два ключевых элемента. Впишите оба пропущенных значения через запятую в порядке появления (например: x, 5).

public interface IComparable
{
    int _____(_____? o);
}
Войдите, чтобы отправить решение
Среднее Ручная проверка Расставьте строки кода в правильном порядке
+20 XP

Строки кода из примера этого урока перемешаны. Впишите их в правильном порядке, каждую строку — с новой строки.

int[] numbers = new int[] { 97, 45, 32, 65, 83, 23, 15 };
    Console.WriteLine(n);
foreach (int n in numbers)
// 15 23 32 45 65 83 97
Array.Sort(numbers);
Войдите, чтобы отправить решение
Сложное Ручная проверка Объясните и модифицируйте пример из урока «Сортировка объектов. Интерфейс IComparable»
+30 XP

Опишите своими словами, что делает приведённый пример кода из урока «Сортировка объектов. Интерфейс IComparable», и предложите одно осмысленное изменение (например, другое входное значение или дополнительное условие). Приведите итоговый код.

int[] numbers = new int[] { 97, 45, 32, 65, 83, 23, 15 };
Array.Sort(numbers);
foreach (int n in numbers)
    Console.WriteLine(n);
// 15 23 32 45 65 83 97
Войдите, чтобы отправить решение
Сложное Ручная проверка Найдите потенциальную проблему в коде урока «Сортировка объектов. Интерфейс IComparable»
+30 XP

Изучите приведённый фрагмент кода и опишите, при каких входных данных или условиях он может сработать не так, как ожидается (граничный случай, отсутствие проверки и т.п.). Предложите исправленный вариант.

public interface IComparable
{
    int CompareTo(object? o);
}
Войдите, чтобы отправить решение
Мини-проект Ручная проверка Мини-проект по теме «Сортировка объектов. Интерфейс IComparable»
+50 XP

Соберите небольшую программу, которая последовательно демонстрирует ключевые идеи урока. Программа должна быть рабочей и содержать минимум два самостоятельно написанных фрагмента, а не просто копию примера из урока.

Войдите, чтобы отправить решение
Домашнее задание Ручная проверка Домашнее задание по теме «Сортировка объектов. Интерфейс IComparable»
+25 XP

Напишите собственную небольшую программу, применяющую материал темы «Сортировка объектов. Интерфейс IComparable». Используйте не менее одной конструкции, показанной в примерах урока. Прикрепите код решения и краткое описание того, что он делает.

Войдите, чтобы отправить решение

Обсуждение (0)

Войдите, чтобы оставить комментарий.