Monday 6 January 2020

Real time example of IEnumerable and IEnumerator in C#

To better understand we will create a list of age
  1. List<int> ages = new List<int>();
  2. ages.Add(10);
  3. ages.Add(20);
  4. ages.Add(30);
  5. ages.Add(40);
  6. ages.Add(50);
Now convert this list to IEnumerable
  1. IEnumerable<int> age_IEnumerable = (IEnumerable<int>)ages;
  2. foreach (int age in age_IEnumerable)
  3. {
  4.     Console.WriteLine(age);
  5. }
There is nothing new, we used foreach here very straight forward, now let’s convert the ages into IEnumerator, there is a method GetEnumerator to convert a list into IEnumerator
  1. IEnumerator<int> age_IEnumerator = ages.GetEnumerator();
  2. while (age_IEnumerator.MoveNext())
  3. {
  4.     Console.WriteLine(age_IEnumerator.Current);
  5. }
As you can see here we used while rather than foreach because foreach cannot be used with IEnumerator, but still there is nothing which can suggest us when should we use IEnumerable and where to IEnumerator.
Before we go further, we should know, IEnumerable uses IEnumerator internally also have a function GetEnumerator to convert into IEnumerator, we should use IEnumerable because it make coding easier and clearer as we can see in above example.
Now let’s discuss the main difference, IEnumerable doesn’t remember the state, which row or record it is iterating while IEnumerator remember it and we are going to see this with example by creating method PrintUpto30 and PrintGreaterThan30
Let’s first check with IEnumerator
  1. public void PrintAgeUpto30(IEnumerator<int> age_IEnumerator)
  2. {
  3.    while (age_IEnumerator.MoveNext()){
  4.       Console.WriteLine(age_IEnumerator.Current);
  5.       if (age_IEnumerator.Current > 20) {
  6.          Console.WriteLine("PrintGreaterThan30 is called");
  7.          PrintGreaterThan30(age_IEnumerator);
  8.       }
  9.    }
  10. }
  11. public void PrintGreaterThan30(IEnumerator<int> age_IEnumerator)
  12. {
  13.     while (age_IEnumerator.MoveNext())
  14.         Console.WriteLine(age_IEnumerator.Current);
  15. }
  16. // Now Call PrintUpto30 which will call PrintGreaterThan30
  17. // by using our previous age IEnumerator
  18. PrintUpto30(IEnumerator);
As we know IEnumerator persists state so once we will call PrintGreaterThan30 by passing age_IEnumerator it will print the remaining list, here is the output:
  1. 10
  2. 20
  3. 30
  4. PrintGreaterThan30 is called
  5. 40
  6. 50
Now let’s check same code with IEnumerable
  1. public void PrintUpto30(IEnumerable<int> age_IEnumerable)
  2. {
  3.     foreach (int age in age_IEnumerable){
  4.        Console.WriteLine(age);
  5.        if (age > 20){
  6.          Console.WriteLine("PrintGreaterThan30 is called");
  7.         PrintGreaterThan30(age_IEnumerable);
  8.       }
  9.    }
  10. }
  11. public void PrintGreaterThan30(IEnumerable<int> age_IEnumerable)
  12. {
  13.   foreach (int age in age_IEnumerable)
  14.     Console.WriteLine(age);
  15. }
// Now Call PrintUpto30 by using our variable age_IEnumerable
PrintAgeUpto30(age_IEnumerable);
Now check the output you will see “PrintGreaterThan30 is called” many times something like this
  1. 10
  2. 20
  3. 30
  4. PrintGreaterThan30 is called
  5. 10
  6. ....
  7. 50
  8. 40
  9. PrintGreaterThan30 is called
  10. 10
  11. ...
  12. 50
  13. 50
  14. PrintGreaterThan30 is called
  15. 10
  16. 50
Conclusion:
  1. Both are interface
  2. IEnumerable code are clear and can be used in foreach loop
  3. IEnumerator use While, MoveNext, current to get current record
  4. IEnumerable doesn’t remember state
  5. IEnumerator persists state means which row it is reading
  6. IEnumerator cannot be used in foreach loop
  7. IEnumerable defines one method GetEnumerator which returns an IEnumerator
  8. IEnumerator allows readonly access to a collection

No comments:

Post a Comment

Baisic Useful Git Commands

  Pushing a fresh repository Create a fresh repository(Any cloud repository). Open terminal (for mac ) and command (windows) and type the be...