Відмінності інтерфейсів 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 реалізує інтерфейс 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 має один індексатор, за допомогою якого ми можемо отримати доступ до будь-якого елемента за його положенням, а також можемо вставити елемент і видалити його в будь-якій позиції.