Internals of loops (While, For and ForEach) in .NET

No.of Views701
Bookmarked0 times
Downloads 
Votes0
By  abhi2434   On  31 Jan 2011 20:01:16
Tag : .NET Frameworks , General
In C# (and VB.NET) we use while, do-while, for and foreach loop to loop through a set of instructions. In this article I will try to demonstrate the basic loops for a while and later on take on a bit about foreach loop and its requirement and finally go deep into its internals.
emailbookmarkadd commentsprint

Images in this article missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at info@codegain.com

 

Introduction

Practically speaking, a loop is the primary building block of a program. We use loop to repeat a set of actions for a certain interval. Now if you think of these intervals, it could be a traversal from one number (called as start index) to another number (called as end index). Very often or probably out of 10 such loop eight times you loop a collection such that you start from 0 and loop until you point to the end of the sequence.

In C# (and VB.NET) we use while, do-while, for and foreach loop to loop through a set of instructions. In this article I will try to demonstrate the basic loops for a while and later on take on a bit about foreach loop and its requirement and finally go deep into its internals.

The Basics

C# comes with three basic types of loops.

1. While Loop : This kind of loop runs while the condition is satisfied.

while (x >= 0)
{
}

2. do-while : This loop runs at least once while the condition is satisfied.

do
{

} while (x >= 10);

3. for : This loop has three sections, index declaration, condition and increment/decrement section. For each call to the instruction the index is incremented and checked with the condition.

for (int i = 0; i < 10; i++)
 {
 }

These are the most basic loops and I hope you already know them and came across with it in your life. .NET introduces another loop called Foreach loop which specially works on an IEnumerable. Each collection in .NET is somehow implements IEnumerable and hence can be used as a part of foreach loop. Hence every sequence (or whatever class) when implements an IEnumerable will have the provision to enumerate through values using foreach.

var enumerable = Enumerable.Range(1, 100);
 foreach (var e in enumerable)
 {

 }

In the above code the instruction within the scope will loop through until the enumerable has value. Now you might wonder why this interface is at all required? Why we need to implement it ? What exactly happens inside these loops. Lets demonstrate these points.

The Internals

Before going further with the internals of loop let me clear out one fact which you always remember. Goto is a construct(keyword) in C# that allows you to unconditionally transfer the control from one place to another. The IL equivalent for goto statement is br.s which takes just an instruction line number to transfer the control to a place. Another small instruction brtrue.s which evaluates the loaded object and moves the control to the instruction line only when the evaluated value turns out to be true.

Hence to summarize :
br.s -> Unconditionally moves the control.
brtrue.s -> Moves the control if loaded value is true.

Now lets start looking at the internals one by one :

While, do - while Loop :

int x=10;
while (x >= 0)
{
}

 

Image Loading

If you look into the IL instruction set it creates an integer variable x (which we have declared in code) and a placeholder for boolean variable. The L_0004 instruction is actually a goto equivalent which moves the control over to the location specified. It evaluates and stores the result of equality of x with 0; clt and  ceq specifies the less than and equal respectively.
Based on the result,  L_0011 is evaluated and control moves to specified instruction line accordingly.

So basically while loop is a sequence of goto statements between an instruction statements to perform a loop. The instruction between L_0005 - L_0008 is the actual action (one inside curl braces of the loop).

Do-while loop is very similar to while loop, with the only difference being the absence of instruction L_0004, and hence lets it to pass through the action.

For Loop :

for (int i = 0; i < 10; i++)
 {
 }

 

Image Loading

The instruction set for the for loop is also very similar to that of while. The for loop creates the index in the first place and stores in zero'th local (L_0002). The goto statement ensures the condition is evaluated and hence moves to L_000b. After the condition is evaluated the L_0012 sends back the control to L_0005. The L_0005 - L_0006 represents the action block(one inside the curl braces) and eventually after that it increments the index  element by 1 and continues.

We kept the instruction set simple using no code inside the action block. The only difference of  for loop with that of while is the extra instruction to store local index and increment it after the execution of action each time.

For-Each Loop:

To understand foreach loop you first need to understand the basics of IEnumerable. In .NET, a collection implementing IEnumerable must implement a method called GetEnumerator which returns an IEnumerator.

IEnumerator actually represents the cursor which points to a certain logical index of the collection. Lets see the IEnumerator interface.

public interface IEnumerator<out T>
{
    T Current { get; }
    bool MoveNext();
    void Reset();
}

Hence the IEnumerator actually keeps track of the state of the collection, which allows you to use the method MoveNext to point to the next location, Current holds the current value of the collection and Reset allows you to re-initialize the cursor.

IEnumerable on the other hand wraps the enumerator into it such that any collection which implements it, can use the foreach loop. I will discuss in-depth about how to generate Enumerable in my next part.

Now let us take an example to demonstrate what is happening inside of a foreach loop :

IEnumerable<int> enumerable = Enumerable.Range(1, 100);
 foreach (int e in enumerable)
 {

 }

The above code actually generates a IEnumerable (collection) of 99 elements from 1 through 100. We loop through the enumerable to get each integer and perform the action on it. Now this is not that simple. Foreach loop is actually broken into the following code after it is been compiled to IL.

var enumerable = Enumerable.Range(1, 100);
IEnumerator<int> enumerator = enumerable.GetEnumerator();
try
{
    while (enumerator.MoveNext())
    {
        int element = enumerator.Current;
        //here goes your action instructions
    }
}
finally
{
    IDisposable disposable = enumerator as System.IDisposable;
    if (disposable != null) disposable.Dispose();
}

I think this looks great to you. Yaah, a foreach loop is actually an abstraction to what we see above. It first finds the enumerator using GetEnumerator from the enumerable, uses MoveNext to loop through the instructions and in the finally block, it tries to dispose the enumerator.

Image Loading

Similar to what I showed in the code above you can see the IL to correspond to the same rule. The try / finally ensures that enumerator is disposed after the foreach loop is complete or even an exception occurs.

Conclusion

So, as you saw most of the IL instructions are goto statements, it is not a good idea or not recommended to write goto statement in your code. As suggested, it is fine with goto as soon as the compiler generates this for you, but it will be horrible if the language does consists a large number of unconditional jumps. So beware.

I hope you like this article, I will continue with IEnumerable in my next article. Stay tune.Thank you for reading.

 
Sign Up to vote for this article
 
About Author
 
abhi2434
Occupation-Not Provided
Company-Not Provided
Member Type-Senior
Location-Not Provided
Joined date-22 Oct 2009
Home Page-Not Provided
Blog Page-Not Provided
 
 
Other popularSectionarticles
Comments
There is no comments for this articles.
Leave a Reply
Title:
Display Name:
Email:
(not display in page for the security purphase)
Website:
Message:
Please refresh your screen using Ctrl+F5
If you can't read this number refresh your screen
Please input the anti-spam code that you can read in the image.
^ Scroll to Top