Отличия интерфейсов IEnumerable, ICollection и IList

IEnumerable, ICollection и IList — это интерфейсы, которые чаще других используются в .Net Framework. Посмотрим, какие возможности они открывают для разработчика.

IEnumerable является основой интерфейсов ICollection и IList (а также многих других). Все эти интерфейсы предоставляют различные функциональные возможности и полезны в различных случаях.

Интерфейс IEnumerable

Мы используем IEnumerable, когда хотим перебирать наши классы, используя цикл foreach

Интерфейс IEnumerable имеет один метод, GetEnumerator, который возвращает интерфейс IEnumerator и помогает перебирать класс с помощью цикла foreach. Интерфейс IEnumerator реализует два метода MoveNext() и Reset(), а также имеет одно свойство Current, которое возвращает текущий элемент в списке.

Создадим класс StoreData для хранения данных целочисленного типа (integer type), этот класс реализует интерфейс IEnumerable. Внутри используем связанный список для хранения данных:

class StoreData : IEnumerable
{
    LinkedList<int> items = new LinkedList<int>();
    public void Add(int i)
    {
       items.AddLast(i);
    }
    public IEnumerator GetEnumerator()
    {
       foreach (var item in items)
       {
          yield return item;
       }
    }
}

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

static void Main(string[] args)  
{  
    StoreData list = new StoreData();  
    list.Add(1);  
    list.Add(2);  
    list.Add(3);  
    list.Add(4);  
  
    foreach (var item in list)  
    {  
        Console.WriteLine(item);  
    }  
              
    Console.ReadLine();  
}  

Предыдущий код отобразит все значения, используя цикл foreach. Вместо цикла foreach также можно использовать следующий код:

IEnumerator enumerator = list.GetEnumerator();  
  
while (enumerator.MoveNext())  
{  
   Console.WriteLine(enumerator.Current);  
}

Цикл foreach работает так же, как и в предыдущем коде. Метод GetEnumerator() доступен с объектом списка, т.к. он реализует интерфейс IEnumerable.

Затем, используя метод MoveNext() и свойство Current класса StoreData, мы можем отобразить данные.

Обратите внимание!

Каждая коллекция внутри .Net Framework реализует интерфейс IEnumerable

Ключевые моменты интерфейса IEnumerable

Он предоставляет доступ к коллекциям только для чтения. Мы не можем изменить какой-либо элемент внутри списка IEnumerable. Он обеспечивает своего рода инкапсуляцию в тех случаях, когда мы не хотим, чтобы наш список изменялся.

Если же мы имеем дело с некоторыми SQL-запросами динамически, это также обеспечивает ленивую загрузку. Это значит, что запросы не будут выполняться до тех пор, пока они нам явно не понадобятся.

Интерфейс ICollection

ICollection унаследован от интерфейса IEnumerable, а это означает, что любой класс, реализующий интерфейс ICollection, также может быть пронумерован с использованием цикла foreach.

В интерфейсе IEnumerable мы не знаем, сколько элементов в коллекции. А вот интерфейс ICollection дает нам это дополнительное свойство для получения количества элементов в коллекции. ICollection Interface содержит следующее:

  • Count Property 
  • IsSynchronized Property
  • SyncRoot Property
  • CopyTo Method

Свойство Count используется для поддержания количества элементов в списке. Свойства IsSysnchronized и SyncRoot помогают сделать коллекцию потокобезопасной. А метод CopyTo копирует всю коллекцию в массив.

Общая версия этого интерфейса также предоставляет методы Add и Remove.

Интерфейс IList

IList реализует интерфейсы ICollection и IEnumerable. Он позволяет нам добавлять и удалять элементы из коллекции, а также обеспечивает поддержку доступа к элементам из индекса. Этот интерфейс обладает большей мощностью, чем предыдущие два интерфейса.

Интерфейс IList содержит следующее:

  • IsFixedSize Property
  • IsReadOnly Property
  • Indexer
  • Add Method
  • Clear Method
  • Contains Method
  • Indexof Method
  • Insert Method
  • Remove Method
  • RemoveAt Method

Интерфейс IList имеет один индексатор, с помощью которого мы можем получить доступ к любому элементу по его положению, а также можем вставить элемент и удалить его в любой позиции.