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.
Let us understand how IEnumerable works.
IEnumerable
Say we have a user-defined class person having properties such as Name, Height, Weight & Sex.
- public class Person
- {
- public string Name { get; set; }
- public string Sex { get; set; }
- public decimal Height { get; set; }
- public int Weight { get; set; }
- }
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
- using I_Cant_See_Sharp.Entities;
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Linq;
-
- namespace I_Cant_See_Sharp
- {
-
- class Program
- {
- static void Main(string[] args)
- {
- List<Person> listOfPersons = new List<Person>()
- {
- new Person()
- {
- Name = "Alex",
- Height = 5.5M,
- Weight = 56,
- Sex = "Male"
- }, new Person()
- {
- Name = "Martin",
- Height = 5.10M,
- Weight = 58,
- Sex = "Male"
- }, new Person()
- {
- Name = "Gloria",
- Height = 5.3M,
- Weight = 52,
- Sex = "Female"
- }, new Person()
- {
- Name = "Sophia",
- Height = 5.7M,
- Weight = 76,
- Sex = "Female"
- }
- };
- Console.WriteLine("-------------------- With Lambda Expressions --------------------------");
- IEnumerable<Person> listOfMales = new List<Person>();
- listOfMales = listOfPersons.Where(male => male.Sex == "Male");
- foreach (var item in listOfMales)
- {
- Console.WriteLine(item.Name);
- }
-
- Console.WriteLine(Environment.NewLine);
- Console.WriteLine("---------------------------- With LINQ --------------------------------");
-
- IEnumerable<Person> listOfFemales = new List<Person>();
- listOfFemales = from female in listOfPersons
- where female.Sex == "Female"
- select female;
- foreach (var item in listOfFemales)
- {
- Console.WriteLine(item.Name);
- }
- }
- }
- }
Now let's check out the output:
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
- IEnumerator<Person> listOfMales = listOfPersons.GetEnumerator();
The following code is a complete example of IEnumarator:
- class Program
- {
- static void Main(string[] args)
- {
- List<Person> listOfPersons = new List<Person>()
- {
- new Person()
- {
- Name = "Alex",
- Height = 5.5M,
- Weight = 56,
- Sex = "Male"
- }, new Person()
- {
- Name = "Martin",
- Height = 5.10M,
- Weight = 56,
- Sex = "Male"
- }, new Person()
- {
- Name = "Gloria",
- Height = 5.3M,
- Weight = 52,
- Sex = "Female"
- }, new Person()
- {
- Name = "Sophia",
- Height = 5.7M,
- Weight = 76,
- Sex = "Female"
- }
- };
- Console.WriteLine("-------------------- Less than 60 --------------------------");
- IEnumerator<Person> listOfLessSixty= listOfPersons.GetEnumerator();
- while (listOfLessSixty.MoveNext())
- {
- if(listOfLessSixty.Current.Weight > 60)
- {
- Console.WriteLine(Environment.NewLine);
- Console.WriteLine("------------------- Greater than 60 -------------------------");
- DisplayFemales(listOfLessSixty);
- }
- else
- {
- Console.WriteLine("Name: "+listOfLessSixty.Current.Name + "Age: " + listOfLessSixty.Current.Weight);
- }
- }
- }
-
- static void DisplayFemales(IEnumerator<Person> listOfGreaterSixty)
- {
- Console.WriteLine("Name: " + listOfGreaterSixty.Current.Name + "Age: " + listOfGreaterSixty.Current.Weight);
- }
- }
Perfect! Let's see an output:
If we had to pass IEnumerable instead of IEnumarator, we will end up printing the list twice.
- using I_Cant_See_Sharp.Entities;
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Linq;
-
- namespace I_Cant_See_Sharp
- {
-
- class Program
- {
- static void Main(string[] args)
- {
- List<Person> listOfPersons = new List<Person>()
- {
- new Person()
- {
- Name = "Alex",
- Height = 5.5M,
- Weight = 56,
- Sex = "Male"
- }, new Person()
- {
- Name = "Martin",
- Height = 5.10M,
- Weight = 56,
- Sex = "Male"
- }, new Person()
- {
- Name = "Gloria",
- Height = 5.3M,
- Weight = 52,
- Sex = "Female"
- }, new Person()
- {
- Name = "Sophia",
- Height = 5.7M,
- Weight = 76,
- Sex = "Female"
- }
- };
-
- IEnumerable<Person> listOfPeople = listOfPersons;
- foreach (var item in listOfPeople)
- {
- Console.WriteLine("Name: " + item.Name + " Age: " + item.Weight);
- if(item.Weight > 60)
- {
- DisplayFemales(listOfPeople);
- }
- }
- }
-
- static void DisplayFemales(IEnumerable<Person> listOfPeople)
- {
- foreach (var item in listOfPeople)
- {
- Console.WriteLine("Name: " + item.Name + " Age: " + item.Weight);
- }
- }
- }
- }
As per code, we are now passing IEnumerable. Let's check out the output:
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 @