For Loops in Depth
Start course

Structures to repeat tasks or access data collections are at the heart of compact and reusable code. C#, like other programming languages, provides three basic mechanisms allowing you to execute statements multiple times dynamically. In this course, we'll take an in-depth look at the for loop, while loop, and foreach loop.

These looping mechanisms vary in structure and intended application, and we'll examine how to use them in different scenarios. In the course of this detailed investigation, you will learn some of the potential pitfalls that accompany programming with each type of loop, how to avoid them, and create efficient loops. There are code examples demonstrating the use of each loop type in a practical way, along with other helpful C# and .NET code snippets.

Learning Objectives

  • An in-depth understanding of for loops
  • Learn about while loop syntax and see how they are used
  • Gain a foundational understanding of object lists
  • Learn how to use, and not to use, a foreach loop to iterate through a list

Intended Audience

This course is intended for those who already have a basic understanding of C# and want to learn about loops.


To get the most out of this course, you should have a basic knowledge of C# as well as an understanding of object orientation and C# classes. Please consider taking our Introduction to Object Orientation and C# Classes course before taking this one.

Source Code

Source code related to the lectures can be found here


A for loop has three parts. An initializer that declares the loop index variable and initializes it to a starting value. Then we have the condition statement, which sets the parameter for the number of times the for loop should execute. Finally, we have the iterator, which specifies how the index variable should be adjusted or changed per iteration of the loop. In most cases, all of these statements are true, as it's common to use a for loop to walk through a data structure like an array or list. An array's first element has the index zero, and we usually want to visit each element to either perform some action or retrieve its contents. I want to look at for loop scenarios other than the default zero-based index, incrementing by one.

The index variable does not have to be an integer; in fact, it can be a floating-point number, and it does not have to be initialized to zero. Depending on your needs, the index variable can be anything from a byte through to a long and even a double or decimal. Many times an INT data type is overkill, and a byte or short would be more appropriate. The main reason we use an INT is habit and convenience, and using a smaller data type will not improve performance. Having said that, using an INT does save us from the problem of the loop wanting to iterate past the capacity of the index variable in most cases. If the for loop condition statement is dynamic, the index is compared to a variable that can change as input data changes; using a smaller index data type may lead to errors.

The condition statement doesn't have to be a less than comparison. It can be less than or equal to, but more crucially, it can be greater than. Combined with a decrementing iterator, we can walk backward through an array.

Not only can the iterator be decremented, but it can change by any value - it doesn't have to be one. You can use pretty much any equation for iteration, but typically the equation will be variable assignment shorthand.

It is possible to modify the iterator and condition variable within a for loop. There may be exceptional situations where this kind of behavior is the most expedient, but generally, you should not do this. This scenario can have unpredictable results and is not how the for loop was intended to be used.

Let's look at some for loop examples illustrating some of this unusual behavior. First off, I want to use a byte variable as a loop index and see what happens when we exceed the index variable's data type capacity. I have a static method called ByteLoop that uses an INT variable called limit on the condition statement. A byte can hold 256 values starting with zero, so when setting the limit to less than 255, the loop should execute with no issues, which it does. What happens when I change the limit to 256? The program does not throw an error but ends up in an endless loop, as the significant bits of the number get pushed out the end of the byte variable, leaving the value of i equal to zero, starting the loop again.

Interestingly, when using a literal value, the C# language extension identifies that 256 is outside a byte's range. This example is a good illustration of ensuring your iterator data type can cope with a dynamic condition statement when using a variable instead of a literal. If you do end up in the situation where visual studio code freezes because your program ends up in an endless loop, you can use the task kill command within Windows to remove the running instances of .NET. Unfortunately, killing the .NET process doesn't necessarily bring VS Code back to life.

Next, I want to demonstrate using a floating-point index with an iterative statement other than incrementing by one. The FloatLoop method starts at 0.2, and we double i by multiplying by two. The reverse loop method does the inverse, starting from a higher value and decreasing by a factor of two until we reach the lower limit.

Finally, let's modify the index variable and the condition boundary variable within the loop. I'm doing this to show you what is possible, but I do not recommend it. I have another method called DumbLoop, where the index's initial value and the condition boundary are passed in as parameters. With a start value of 3, the loop completes despite the limit increasing and the index being decremented each iteration. However, changes in the initial start value can have dire consequences. For instance, if the start value is zero, then the index value would become negative, as zero times two equals zero, and then we subtract one from i making it negative. The INT value i decreases until we hit the negative limit of the INT data type, ending up, once again, in an endless loop.

About the Author
Learning Paths

Hallam is a software architect with over 20 years experience across a wide range of industries. He began his software career as a  Delphi/Interbase disciple but changed his allegiance to Microsoft with its deep and broad ecosystem. While Hallam has designed and crafted custom software utilizing web, mobile and desktop technologies, good quality reliable data is the key to a successful solution. The challenge of quickly turning data into useful information for digestion by humans and machines has led Hallam to specialize in database design and process automation. Showing customers how leverage new technology to change and improve their business processes is one of the key drivers keeping Hallam coming back to the keyboard. 

Covered Topics