Для чего используется интерфейс IList в C#?

«Для чего используется интерфейс IList в C#?» — вопрос из категории C# Core, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Интерфейс IList<T> (и его неуниверсальная версия IList) представляет упорядоченную коллекцию объектов, доступ к которым возможен по индексу. Он расширяет ICollection<T> и IEnumerable<T>, добавляя методы для вставки, удаления и доступа к элементам по позиции.

Основные методы IList<T>:

  • int IndexOf(T item) – находит индекс первого вхождения элемента.
  • void Insert(int index, T item) – вставляет элемент в указанную позицию.
  • void RemoveAt(int index) – удаляет элемент по индексу.
  • T this[int index] { get; set; } – индексатор для доступа к элементам.

Пример использования:

// Объявление через интерфейс позволяет абстрагироваться от конкретной реализации
IList<string> collection = new List<string> { "Apple", "Banana" };

collection.Insert(1, "Orange"); // Вставка по индексу 1: ["Apple", "Orange", "Banana"]
collection.RemoveAt(0); // Удаление первого элемента: ["Orange", "Banana"]
string fruit = collection[0]; // Доступ по индексу: "Orange"
int pos = collection.IndexOf("Banana"); // pos = 1

Зачем использовать IList<T> вместо List<T>?

  1. Абстракция и тестирование: Позволяет писать код, зависящий от контракта (доступ по индексу, модификация), а не от конкретного класса. Это упрощает подмену реализации (например, на ObservableCollection<T> в WPF или мок-объект в тестах).
  2. Ограничение возможностей: Возвращая IList<T> из публичного API, вы явно указываете, что коллекция поддерживает индексирование и модификацию. Если модификация не предполагается, лучше вернуть IReadOnlyList<T>.

Важные нюансы:

  • Не все реализации IList<T> поддерживают изменение. Например, ArraySegment<T> реализует IList<T>, но методы Add, Insert и RemoveAt выбрасывают NotSupportedException.
  • Для большинства внутренних операций, где известна конкретная реализация, предпочтительнее использовать List<T> напрямую для максимальной производительности.