The IEnumerable interface is the base Interface for many collections in C#, and its job is to provide a way of iteration through a collection. That is why we can use for each loops to go through a List or a Dictionary. In simple English when a collection class implements the IEnumerable interface it becomes countable, and we can count each element in it individually

There are 2 versions of the IEnumerable Interface

1.IEnumerable <T> for generic collections

2.IEnumerable for nongeneric collections

But since generic collections were introduced later after the non-generic ones and it is no longer recommended to use the non-generic collections in a new project due to their need to perform boxing and unboxing (converting the types of objects), we will explain how to use the

IEnumerable <T> interface in this lesson

IEnumerable<T> contains a single method that you must implement when implementing this interface; GetEnumerator(), which returns an IEnumerator<T> object. The returned IEnumerator<T> provides the ability to iterate through the collection by exposing a Current property that points at the object we are currently at in the collection.

IEnumerables have a method to get the next item in the collection, so they look at items “one at a time,” they don’t need the whole collection to be in memory. They don’t know how many items are in it for each loop. It just keeps getting the next item until it runs out. IEnumerables also help ensure immutability (read-only)

when it is recommended to use the IEnumerable interface:

  • Your collection represents a massive database table, you don’t want to copy the entire thing into memory and cause performance issues in your application.

When it is not recommended to use the IEnumerable interface:

  • You need the results right away and are possibly mutating/editing the objects later on. In this case, it is better to use an Array or a List

Making your Classes Enumerable

In this example, we will see how to make our class Enumerable meaning we can use an instance of it inside a for each loop

let’s consider the following classes

Class 1: a class called dog which has two properties

  1. string Name
  2. bool IsNaughtyDog

and one method

  1. GiveTreat() which will cause the dog to say “wuf” on the console :)

Class 2: a class called DogShelter

Which contains the List of dogs and that’s it

The List of dogs is initialized in the constructor

Now in the main method let’s create a new DogShelter object and try to Enumerate through it

using a for each loop

We will Immediately see an error , This error is saying that our class lacks the ability to be Enumerated through

To fix this we need to implement the interface IEnumerbale<T> where T is going to be the type of objects that we will enumerate through which in our case is Dog

first, since this interface is concerned with the generic collections, we need to import the generic collections namespace

after we implement the interface IEnumerable<Dog> our class should look like this

Now the error inside the for each loop is gone, but another error has appeared on the IEnumerable<Dog>

It is complaining because we did not implement the two methods that are inside the IEnumerable Interface, which are

  1. IEnumerable<Dog>.GetEnumerator() which is the method we need to implement to make our class Enumerable.
  2. IEnumerable.GetEnumerator() which is the non-generic version of the first method

Now the reason we need to implement the second method (non-generic version) is to ensure backward compatibility with the non-generic collections just in case because the generic collections came after the non-generic collections

Let’s hit show potential fixes

and then select Implement Interface

These will the two methods we mentioned above in our class

The class should look like this afterward

Now since generic collections implement the IEnumerable Interface, then they also have their own implementation of the GetEnumerator() method, Which means in our case since the DogShelter uses a List<Dog> as a collection then we can use the GetEnumerator() of that list as a workaround

Our DogShelter class should then look like this

Complete Code