Daily Knowledge Drop
In C#, a for loop
is lowered to a while loop
by the compiler.
At a lower level, the for
loop does not exist - it gets translated into a while
loop by the C# compiler, and then is executed as such.
Lowering
Done by the C# compiler, lowering
is the process of rewriting high-level language features, into low-level language features in the same language.
There are a number of C# features, which are just syntactic sugar over (often) more complex lower-level features - the compiler will take the high-level feature and lower it to the lower-level feature.
Lowering is done for a number of reasons, including:
- Working with high-level features, are easier and simpler to work with
- Optimization
This post is specifically about the for
loop, not an especially complex feature - however it is more complex than the while
loop, its lower-level equivalent.
For loop
Using sharplab.io, one is able to see the lowered code the compiler generates.
Here is an example of some code written in Visual Studio:
public void ForLoopExample()
{
for(int i = 0; i < 100; i++)
{
Console.WriteLine(i);
}
}
And the lowered code the compiler generates:
public void ForLoopExample()
{
int num = 0;
while (num < 100)
{
Console.WriteLine(num);
num++;
}
}
As you can see - the for
loop is converted to a while
loop!
Another example, in a previous post we learnt how the iterator section of a for loop could contain multiple statements. Looking at the lowered code for that example, the while
loop is controlled only by the condition section of the for
loop - this is why this portion of the for loop can only contain one statement, while the other sections can contain multiple.
Original C# code:
public void ForLoopExample2()
{
int countDown = 100;
for(int i = 0; i < 100; i++, countDown--)
{
Console.WriteLine(i);
}
}
And the lowered code the compiler generates:
public void ForLoopExample2()
{
int num = 100;
int num2 = 0;
while (num2 < 100)
{
Console.WriteLine(num2);
num2++;
num--;
}
}
Foreach
Just for reference, the foreach
does not operate the same way as the for
loop - even though both iterate through a list of items, they do it very differently.
Foreach
works using the GetEnumerator method on a class, and is not lowered to a while
loop:
Original C# code:
public void ForEachLoopExample()
{
var list = new List<int> { 1, 2, 3, 4, 5, };
foreach (var item in list)
{
Console.WriteLine(item);
}
}
And the lowered code the compiler generates:
public void ForEachLoopExample()
{
List<int> list = new List<int>();
list.Add(1);
list.Add(2);
list.Add(3);
list.Add(4);
list.Add(5);
List<int> list2 = list;
List<int>.Enumerator enumerator = list2.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
int current = enumerator.Current;
Console.WriteLine(current);
}
}
finally
{
((IDisposable)enumerator).Dispose();
}
}
While the developer written code for a for
and foreach
loop are fairly similar - the lowered code for the foreach
is a bit more complex than a simple while
loop.
Notes
While this may not be something one has to worry or think about when coding - its always good to have a general knowledge of how the compiler works, and what its doing (even at a high level), and how the code written impacts the lowered code which gets executed.
References
Daily Drop 113: 08-07-2022
At the start of 2022 I set myself the goal of learning one new coding related piece of knowledge a day.
It could be anything - some.NET / C# functionality I wasn't aware of, a design practice, a cool new coding technique, or just something I find interesting. It could be something I knew at one point but had forgotten, or something completely new, which I may or may never actually use.
The Daily Drop is a record of these pieces of knowledge - writing about and summarizing them helps re-enforce the information for myself, as well as potentially helps others learn something new as well.On This Page