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

Класс ObservableCollection

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

Кроме стандартных классов коллекций типа списков, очередей, словарей, стеков .NET также предоставляет специальный класс ObservableCollection<T>. В отличие от ранее рассмотренных коллекций данный класс определен в пространстве имен System.Collections.ObjectModel. По функциональности коллекция ObservableCollection похожа на список List за тем исключением, что позволяет известить внешние объекты о том, что коллекция была изменена.

Создание и инициализация ObservableCollection

Для создания объекта класс ObservableCollection предоставляет ряд конструкторов. Прежде всего мы можем создать пустую коллекцию:


using System.Collections.ObjectModel;

ObservableCollection<string> people = new ObservableCollection<string>();

В данном случае коллекция people типизируется типом string, поэтому может хранить только строки.

Другая версия конструктора позволяет передать в ObservableCollection объекты из другой коллекции или массива:


var people = new ObservableCollection<string>( new string[] {"Tom", "Bob", "Sam"});

Для инициализации можно через инициализатор в фигурных скобках передать значения


var people = new ObservableCollection<string>
{
    "Tom", "Bob", "Sam"
};

Также можно сочетать предыдущие два способа:


var people = new ObservableCollection<string>( new string[] {"Mike", "Alice", "Kate" })
{
    "Tom", "Bob", "Sam"
};

Обращение к элементам коллекции

Для обращения к элементам ObservableCollection можно применять индексы на манер массивов или списков List:


var people = new ObservableCollection<string>
{
    "Tom", "Bob", "Sam"
};

// получаем первый элемент
Console.WriteLine(people[0]);   // Tom
// изменяем первый элемент
people[0] = "Tomas";
Console.WriteLine(people[0]);   // Tomas

Перебор коллекции

Для перебора коллекции можно применять стандартные циклы:


using System.Collections.ObjectModel;

var people = new ObservableCollection<string>
{
    "Tom", "Bob", "Sam"
};

foreach(var person in people)
{
    Console.WriteLine(person);
}
for (int i =0; i < people.Count; i++)
{
    Console.WriteLine(people[i]);
}

С помощью свойства Count можно получить количество элементов в коллекции.

Методы ObservableCollection

Среди методов класса ObservableCollection можно отметить следующие:

  • void Add(T item): добавление нового элемента в коллекцию

  • void CopyTo(T[] array, int index,): копирует в массив array элементы из коллекции начиная с индекса index

  • bool Contains(T item): возвращает true, если элемент item есть в коллекции

  • void Clear(): удаляет из коллекции все элементы

  • int IndexOf(T item): возвращает индекс первого вхождения элемента в коллекции

  • void Insert(int index, T item): вставляет элемент item в коллекцию по индексу index. Если такого индекса в коллекции нет, то генерируется исключение

  • bool Remove(T item): удаляет элемент item из коллекции, и если удаление прошло успешно, то возвращает true. Если в коллекции несколько одинаковых элементов, то удаляется только первый из них

  • void RemoveAt(int index): удаление элемента по указанному индексу index. Если такого индекса в коллекции нет, то генерируется исключение

  • void Move(int oldIndex, int newIndex): перемещает элемент с индекса oldIndex на позицию по индексу newIndex

Применение методов:


using System.Collections.ObjectModel;

var people = new ObservableCollection<string>();

// добавляем элемент
people.Add("Bob");
// вставляем элемент по индексу 0
people.Insert(0, "Tom");

// проверка наличия элемента 
bool bobExists = people.Contains("Bob");     // true
Console.WriteLine($"Bob exists: {bobExists}");
bool mikeExists = people.Contains("Mike");   // false
Console.WriteLine($"Mike exists: {mikeExists}");

// удаляем элемент
people.Remove("Tom");
// удаляем элемент по индексу 0
people.RemoveAt(0);

Уведомление об измении коллекции

Класс ObservableCollection определяет событие CollectionChanged, подписавшись на которое, мы можем обработать любые изменения коллекции. Данное событие представляет делегат NotifyCollectionChangedEventHandler:

void NotifyCollectionChangedEventHandler(object? sender, NotifyCollectionChangedEventArgs e);

Второй параметр делегата - объект NotifyCollectionChangedEventArgs хранит всю информацию о событии. В частности, его свойство Action позволяет узнать характер изменений. Оно хранит одно из значений из перечисления NotifyCollectionChangedAction:

  • NotifyCollectionChangedAction.Add: добавление

  • NotifyCollectionChangedAction.Remove: удаление

  • NotifyCollectionChangedAction.Replace: замена

  • NotifyCollectionChangedAction.Move: перемещение объекта внутри коллекции на новую позицию

  • NotifyCollectionChangedAction.Reset: сброс содержимого коллекции (например, при ее очистке с помощью метода Clear())

Кроме того, свойства NewItems и OldItems позволяют получить соответственно добавленные и удаленные объекты. Таким образом, мы получаем полный контроль над обработкой добавления, удаления и замены объектов в коллекции.

Допустим, у нас будет следующий класс Person, который представляет пользователя:


class Person
{
    public string Name { get; }
    public Person(string name) => Name = name;
}

Для управления коллекцией объектов Person определим следующую программу:


using System.Collections.ObjectModel;
using System.Collections.Specialized;

var people = new ObservableCollection<Person>() 
{ 
    new Person("Tom"), 
    new Person("Sam") 
};
// подписываемся на событие изменения коллекции
people.CollectionChanged += People_CollectionChanged;

people.Add(new Person("Bob"));  // добавляем новый элемент

people.RemoveAt(1);                 // удаляем элемент
people[0] = new Person("Eugene");   // заменяем элемент

Console.WriteLine("\nСписок пользователей:");
foreach (var person in people)
{
    Console.WriteLine(person.Name);
}
// обработчик изменения коллекции
void People_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
    switch (e.Action)
    {
        case NotifyCollectionChangedAction.Add: // если добавление
            if(e.NewItems?[0] is Person newPerson)
                Console.WriteLine($"Добавлен новый объект: {newPerson.Name}");
            break;
        case NotifyCollectionChangedAction.Remove: // если удаление
            if (e.OldItems?[0] is Person oldPerson)
                Console.WriteLine($"Удален объект: {oldPerson.Name}");
            break;
        case NotifyCollectionChangedAction.Replace: // если замена
            if ((e.NewItems?[0] is Person replacingPerson)  && 
                (e.OldItems?[0] is Person replacedPerson))
                Console.WriteLine($"Объект {replacedPerson.Name} заменен объектом {replacingPerson.Name}");
            break;
    }
}

Здесь в качестве обработчика изменений коллекции выступает метод People_CollectionChanged, в котором с помощью параметра NotifyCollectionChangedEventArgs получаем информацию об изменении. Консольный вывод программы:

Добавлен новый объект: Bob
Удален объект: Sam
Объект Tom заменен объектом Eugene

Список пользователей:
Eugene
Bob

Проверь себя

📋 Тест по теме «Класс ObservableCollection» Тест по теме

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

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

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

using _____.Collections.ObjectModel;

ObservableCollection<string> people = new ObservableCollection<string>();
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (2)
+10 XP

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

var people = _____ ObservableCollection<string>( new string[] {"Tom", "Bob", "Sam"});
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (3)
+10 XP

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

var people = new _____<string>
{
    "Tom", "Bob", "Sam"
};
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (4)
+10 XP

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

var people = _____ ObservableCollection<string>( new string[] {"Mike", "Alice", "Kate" })
{
    "Tom", "Bob", "Sam"
};
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (5)
+10 XP

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

var people = new ObservableCollection<string>
{
    "Tom", "_____", "Sam"
};

// получаем первый элемент
Console.WriteLine(people[0]);   // Tom
// изменяем первый элемент
people[0] = "Tomas";
Console.WriteLine(people[0]);   // Tomas
Войдите, чтобы отправить решение
Среднее Ручная проверка Восстановите код по памяти (1)
+20 XP

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

using System.Collections.ObjectModel;

_____<string> people = new ObservableCollection<string>();
Войдите, чтобы отправить решение
Среднее Ручная проверка Восстановите код по памяти (2)
+20 XP

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

var people = _____ ObservableCollection<string>( new string[] {"Tom", "Bob", "Sam"});
Войдите, чтобы отправить решение
Среднее Ручная проверка Расставьте строки кода в правильном порядке
+20 XP

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

var people = new ObservableCollection<string>
};
    "Tom", "Bob", "Sam"
{
Войдите, чтобы отправить решение
Сложное Ручная проверка Объясните и модифицируйте пример из урока «Класс ObservableCollection»
+30 XP

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

using System.Collections.ObjectModel;

ObservableCollection<string> people = new ObservableCollection<string>();
Войдите, чтобы отправить решение
Сложное Ручная проверка Найдите потенциальную проблему в коде урока «Класс ObservableCollection»
+30 XP

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

var people = new ObservableCollection<string>( new string[] {"Tom", "Bob", "Sam"});
Войдите, чтобы отправить решение
Мини-проект Ручная проверка Мини-проект по теме «Класс ObservableCollection»
+50 XP

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

Войдите, чтобы отправить решение
Домашнее задание Ручная проверка Домашнее задание по теме «Класс ObservableCollection»
+25 XP

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

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

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

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