IEnumerable And IEnumerator In C#

Introduction

 
We are blessed with a bunch of collections to use in C#. And the collection is no good if we can't iterate through them.
 
Well, C# has these 3 interfaces to do the work. Each one of them functions specifically with their qualities.
 
Before we understand their meaning. We first need to know their structure in C# 9.
 
Following UML will give you an understanding of their place in C# and which namespaces they belong to.
 
IEnumerable And IEnumerator In C#
 
Let us understand how IEnumerable works.
 
IEnumerable
 
Say we have a user-defined class person having properties such as Name, Height, Weight & Sex.
  1. public class Person  
  2.    {  
  3.        public string Name { getset; }  
  4.        public string Sex { getset; }  
  5.        public decimal Height { getset; }  
  6.        public int  Weight { getset; }  
  7.    } 
Now in our Main method first we need to initialize the list, then we will iterate it using IEnumerable with LINQ & Lambda expressions.
  • The list will have 2 males & 2 females
  • Iterate males using lambda
  • Iterate females using LINQ
  1. using I_Cant_See_Sharp.Entities;  
  2. using System;  
  3. using System.Collections;  
  4. using System.Collections.Generic;  
  5. using System.Linq;  
  6.   
  7. namespace I_Cant_See_Sharp  
  8. {  
  9.   
  10.     class Program  
  11.     {  
  12.         static void Main(string[] args)  
  13.         {  
  14.             List<Person> listOfPersons = new List<Person>()  
  15.             {  
  16.                 new Person()  
  17.                 {  
  18.                     Name = "Alex",  
  19.                     Height = 5.5M,  
  20.                     Weight = 56,  
  21.                     Sex = "Male"  
  22.                 }, new Person()  
  23.                 {  
  24.                     Name = "Martin",  
  25.                     Height = 5.10M,  
  26.                     Weight = 58,  
  27.                     Sex = "Male"  
  28.                 }, new Person()  
  29.                 {  
  30.                     Name = "Gloria",  
  31.                     Height = 5.3M,  
  32.                     Weight = 52,  
  33.                     Sex = "Female"  
  34.                 }, new Person()  
  35.                 {  
  36.                     Name = "Sophia",  
  37.                     Height = 5.7M,  
  38.                     Weight = 76,  
  39.                     Sex = "Female"  
  40.                 }  
  41.             };  
  42.             Console.WriteLine("-------------------- With Lambda Expressions  --------------------------");  
  43.             IEnumerable<Person> listOfMales = new List<Person>();  
  44.             listOfMales = listOfPersons.Where(male => male.Sex == "Male");  
  45.             foreach (var item in listOfMales)  
  46.             {  
  47.              Console.WriteLine(item.Name);  
  48.             }  
  49.   
  50.             Console.WriteLine(Environment.NewLine);  
  51.             Console.WriteLine("---------------------------- With LINQ  --------------------------------");  
  52.               
  53.             IEnumerable<Person> listOfFemales = new List<Person>();  
  54.             listOfFemales = from female in listOfPersons  
  55.                             where female.Sex == "Female"  
  56.                             select female;  
  57.             foreach (var item in listOfFemales)  
  58.             {  
  59.                 Console.WriteLine(item.Name);  
  60.             }  
  61.         }  
  62.     }  

Now let's check out the output:
 
IEnumerable And IEnumerator In C#
 
IEnumerator
 
Let's divide our list based on Weight.

Weight < 60 & weight > 60
 
The list has a GetEnumator function, as we have also seen this in UML above. This function returns an IEnumerator of generics
  • MoveNext()
    It jumps on the next record: Helps to traverse the list. basically it does position++       

  • Reset()
    Reset the list which then points back to the -1 index. It makes  position = -1

  • Current
    Returns the current object.
  • Advantage
    It remembers the current state. How?

    • Let's understand this with an example, we will print all persons with age less than 60 and then pass the same list to new function, here new function will start printing the list from same index where it was left rather than starting from the 1st index again.
With above listOfPerson we can do as follows to get an IEnumarator
  1. IEnumerator<Person> listOfMales = listOfPersons.GetEnumerator();             
 The following code is a complete example of IEnumarator:
  1. class Program  
  2.   {  
  3.       static void Main(string[] args)  
  4.       {  
  5.           List<Person> listOfPersons = new List<Person>()  
  6.           {  
  7.               new Person()  
  8.               {  
  9.                   Name = "Alex",  
  10.                   Height = 5.5M,  
  11.                   Weight = 56,  
  12.                   Sex = "Male"  
  13.               }, new Person()  
  14.               {  
  15.                   Name = "Martin",  
  16.                   Height = 5.10M,  
  17.                   Weight = 56,  
  18.                   Sex = "Male"  
  19.               }, new Person()  
  20.               {  
  21.                   Name = "Gloria",  
  22.                   Height = 5.3M,  
  23.                   Weight = 52,  
  24.                   Sex = "Female"  
  25.               }, new Person()  
  26.               {  
  27.                   Name = "Sophia",  
  28.                   Height = 5.7M,  
  29.                   Weight = 76,  
  30.                   Sex = "Female"  
  31.               }  
  32.           };  
  33.           Console.WriteLine("-------------------- Less than 60  --------------------------");  
  34.           IEnumerator<Person> listOfLessSixty= listOfPersons.GetEnumerator();  
  35.           while (listOfLessSixty.MoveNext())  
  36.           {  
  37.               if(listOfLessSixty.Current.Weight > 60)  
  38.               {  
  39.                   Console.WriteLine(Environment.NewLine);  
  40.                   Console.WriteLine("------------------- Greater than 60  -------------------------");  
  41.                   DisplayFemales(listOfLessSixty);  
  42.               }  
  43.               else  
  44.               {  
  45.               Console.WriteLine("Name: "+listOfLessSixty.Current.Name + "Age: " + listOfLessSixty.Current.Weight);  
  46.               }  
  47.           }  
  48.       }  
  49.   
  50.       static void DisplayFemales(IEnumerator<Person> listOfGreaterSixty)  
  51.       {  
  52.               Console.WriteLine("Name: " + listOfGreaterSixty.Current.Name + "Age: " + listOfGreaterSixty.Current.Weight);  
  53.       }  
  54.   } 
Perfect! Let's see an output:
 
IEnumerable And IEnumerator In C#
 
If we had to pass IEnumerable instead of IEnumarator, we will end up printing the list twice.
  1. using I_Cant_See_Sharp.Entities;  
  2. using System;  
  3. using System.Collections;  
  4. using System.Collections.Generic;  
  5. using System.Linq;  
  6.   
  7. namespace I_Cant_See_Sharp  
  8. {  
  9.   
  10.     class Program  
  11.     {  
  12.         static void Main(string[] args)  
  13.         {  
  14.             List<Person> listOfPersons = new List<Person>()  
  15.             {  
  16.                 new Person()  
  17.                 {  
  18.                     Name = "Alex",  
  19.                     Height = 5.5M,  
  20.                     Weight = 56,  
  21.                     Sex = "Male"  
  22.                 }, new Person()  
  23.                 {  
  24.                     Name = "Martin",  
  25.                     Height = 5.10M,  
  26.                     Weight = 56,  
  27.                     Sex = "Male"  
  28.                 }, new Person()  
  29.                 {  
  30.                     Name = "Gloria",  
  31.                     Height = 5.3M,  
  32.                     Weight = 52,  
  33.                     Sex = "Female"  
  34.                 }, new Person()  
  35.                 {  
  36.                     Name = "Sophia",  
  37.                     Height = 5.7M,  
  38.                     Weight = 76,  
  39.                     Sex = "Female"  
  40.                 }  
  41.             };  
  42.             //Console.WriteLine("-------------------- Weight Less than 60  --------------------------");  
  43.             IEnumerable<Person> listOfPeople = listOfPersons;  
  44.             foreach (var item in listOfPeople)  
  45.             {  
  46.                 Console.WriteLine("Name: " + item.Name + " Age: " + item.Weight);  
  47.                 if(item.Weight > 60)  
  48.                 {  
  49.                     DisplayFemales(listOfPeople);  
  50.                 }  
  51.             }  
  52.         }  
  53.   
  54.         static void DisplayFemales(IEnumerable<Person> listOfPeople)  
  55.         {  
  56.             foreach (var item in listOfPeople)  
  57.             {  
  58.                 Console.WriteLine("Name: " + item.Name + " Age: " + item.Weight);  
  59.             }  
  60.         }  
  61.     }  

As per code, we are now passing IEnumerable. Let's check out the output:
 
IEnumerable And IEnumerator In C#
 
As per output, it is clear that IEnumerable does not remember the current state it was processing. Thus it starts processing back from the 1st index.
 

Conclusion

 
In this article, we learned how to and when to use IEnumerable & IEnumerator.
 
What are the properties & methods of these interfaces we can use?
 
In the next article, we will learn how everything about IQueryable.
 
I hope you now have a basic understanding of these iterators. Use them in your C# code as per the project's requirement.
 
If you want to say hello, connect with me @