C# For Each – Iterating the objective way in 2024

C# For Each - Iterating the objective way
C# For Each – Iterating the objective way

C# For Each – I want them all!

So you want to use the C# For Each loop to go through a bunch of – well – „things“? No problem! In today’s post we are going to talk about the famous loop called „for each“. Next to the basic exaplanation of the loop itself, I will also provide many examples being ready to use.

Going even further, we will also discuss some alternatives and what to use when. Sometimes it’s actually „better“ to not use the „objective“ approach with the C# For Each Loop at all, but we will take a look at an example in just a few moments.

💡 In a hurry, just looking for a snippet? No problem, scroll to the basic explanation or the quick examples section down below! Feel free to use the table of contents as well. Make sure you don’t miss out on those tips and important notes.

What is a „loop“ in the first place?

As the name already inherits from like the context of airplanes it means „doing something again“. Or otherwise said, you can talk about „repeating“ things. There may be (and will be) some cases in programming, where you want a specific code block to be executed multiple times. Allthough being executed multiple times, you might want to have some „tweaks“ to those so called iterations.

Think for example of some kind of number guessing game. In our example we will generate 6 random numbers and compare them to the 6 input numbers of the user. As a beginner knowing some basic „Command“-ish programming with the Console (meaning do this, do that), you might start like this:

var random = new Random();

var randomNumber1 = random.Next(1, 50);
var randomNumber2 = random.Next(1, 50);
// ... 3, 4, 5, 6

Console.WriteLine($"Hey, please enter 6 numbers between 1 and 49 and confirm them with enter");
var enteredNumber1 = Convert.ToInt32(Console.ReadLine());
var enteredNumber2 = Convert.ToInt32(Console.ReadLine());
// 3, 4, 5, 6

As you might have guessed (or will find out now 😛), this is not pretty good. We have a lot of repetetive code, which is generally a sign of bad code. So how could we actually change this to some better kind of code?

We can group those two tasks by summing it up like this: „Generate 6 random numbers“ and „Take 6 numbers from the users input“. So we could basically say we have a „counter“ on how often a specific block (generating a number / receiving input) should be executed.

Improving our smelly code

To start improving the above code we could just start by composing the first part into one coherent function. I will even go a step further, making the amount of generated (and later – input) numbers configurable. But I won’t go „too far“ making the generated range like configurable or using better tools to do a part of this task (like using „Range“ from Enumerable).

private List<int> GetRandomNumbers(int count)
{
  // usually there is a thing about instanting the random class multiple times,
  // = for each function call, but this is no topic for this post here :)
  var random = new Random();
  var randomNumbers = new List<int>();
  for (var i = 1; i <= count; i++) {
    var randomNumber = random.Next(1, 50);
    randomNumbers.Add(randomNumber);
  }
}

Conclusion

So these were the basics about using loops in general. We learned, that loops are there for executing a specific block of code multiple times and eventually / rather mostly with some little tweaks. Now we are ready to jump further ahead, talking about the more „objective“ approach using the C# For Each loop.

What is a C# For Each Loop then?

As shown above, we had an example using something like a „counter“ (well at least something to count on I guess – meh). But what if we don’t need or even don’t have a counter? What if I would prefer to send „each“ selected customer an email?

You guessed it right, this is where the „for each“ comes in, or better written „foreach“ in C#. Going or iterating over „each“ object – as the naming already suggests – is mostly used when iterating „thing“ based. No matter if you have your favourite cracker snack like „I’m going to eat each of those crackers“, or your favourite energy drink.

Basic explanation

To do so, you have to basically pick every cracker after each other and do something (eat it). This is exactly how the C# For Each Loop works, lemme explain with a code snippet:

// foreach -> keyword indicating that now there will be a foreach loop
// () _> parantheses, open & closed
// var / string / Button / .. ->
// cracker -> variable name to have access to each "thing" in each iteration
// in -> keyword to say like "this is the collection I want to iterate through"
// crackers -> something that is enumerable / iterable (implementing IEnumerable interface)
foreach (var cracker in crackers) {
  // code which you want to execute for each cracker
  person.Eat(cracker);
}

The first thing is the actual keyword indicating, that there will be a „for each loop“ now. Then there has to be an opening and a closing bracket, to define some things for the loop. Next, you have to define the type of the things you are iterating over: If it’s a list of crackers, well, then one of them is a cracker. If you are iterating over customers, then one of them is basically a single customer.

Of course it can get more complicated if we take different interfaces, generics, etc. into account, but let’s skip this for now. After specifying the type of the iteration variable, you name the variable itself. Of course you can name it anything you want, but you should stick to basic naming conventions. Either you, your team, or maybe your boss has the guidelines for you here.

Usually you call the variable the singular form of what you are going to iterate over. Then there is the next keyword called „in“, which obviously tells the for each loop what to iterate over. The last part mentions the collection (better said enumerable) itself – the things you want to iterate through.

Which (control) types of loops exists?

As you may have guessed this isn’t all to it. Next to those basic types of loops, there is at least one more distinction as well. You could also call this like „category“, let me introduce you: the control type / section.

Head controlled

So far you have seen something like the following, in the head of the loop. We basically explained to the loop, when to actually start and how long it should run. By how long, it’s not about like a stopwatch or something like that, more like „continue under which condition“. Let’s dive deeper..

In the image above, you can see the head, marked as green rectangle. This actually means, check the condition, before you start the actual loop. Then there are 3 single rectangles:

  1. Where to start / to initialize?
  2. When to actually execute (or continue executing)?
  3. What to do after an execution?

The first rectangle is showing the start / (let’s call it) initializer section. It basically initializes this counter variable called „i“ and defines the starting point. It’s value is coming from our passed variable called „start“, but could also be just a numeric literal like „0“. Of course this would mean: „Start at zero“.

In the second section we have the condition on when to actually execute the body of the loop. This does not only count (pun intended!) for the start of the loop! It also defines the condition to check before continueing with each iteration of the loop. So if this section returns „false“ at some point, it won’t continue or won’t even start executing.

At the very end – section 3 – there is this increment operation, which adds „1“ to the „i“ counter variable. This is actually executed after each executed body part of the loop. If we wouldn’t do this, our loop would never „proceed“, because „i“ would never change. It couldn’t detect „where am I right now?“, or „should I stop now?“

Foot controlled

After seeing the head controlled loop type / category, let’s take a look at the foot controlled one. Even if it’s pretty similar to the head controlled one, it’s actually different and can help in other scenarios. I’m trying to come up with a fitting, real-life example:

Foot Controlled Do loop
Foot Controlled Do loop

Right in the image above, you can see some kind of logic to wait for a browser element to be visible. I could of course made it more variable by passing some kind of element id, but not for this example. Just imagine navigating to a website and waiting for a specific element to appear.

The gotcha in this scenario is, that the loop body will at least execute once, as it’s foot controlled. After each run, it will check like „should I run again?“, this is done by the condition marked with the green rectangle.

Mostly the homepage would definately need some time to load and render, so we could say: We need to wait anyways. So I started with preparing a flag which indicates, if we could find the element. Inside the loop (even in the first run), I told it to wait first and then try to get the element. At the bottom it will then check if it has found the element, if not, it will continue waiting and (try) getting the element.

Of course you would add more things like a timeout, or similar things in a production like code.

When not to use For Each in C#

Well as I mentioned in the beginning of this post, there are some cases where you might want to avoid using a for each loop. There are two prominent examples, which instantly come to my mind when strictly thinking about „when not to use For Each“. The first one will be a rather simple example and the second one is one common problem, when beginners first work with like chat applications, servers, etc. So let’s start with the 0 *cough* I mean 1st example 😉!

When you still need a counter / indexer anyways

So the first basic example of „when not to use the For Each loop“ coming to my mind is like this. Imagine, you have some sort of objects (let them be customers) which you want to process. Let’s continue with making a little customer class and by writing some dummy code for the processing:

public class Customer
{

  public string CompanyName { get; set; }

  public string FirstName { get; set; }

  public string LastName { get; set; }

  // ...

}


private void ProcessCustomers(List<Customer> customers)
{
  foreach (var customer in customers) {
    ProcessCustomer(customer);
  }
}

private void ProcessCustomer(Customer customer)
{
  // do some work with the obj..
}

// somewhere in the form.
private void Form1_Load(object? sender, EventArgs e)
{
  var customers = new List<Customer>();
  customers.Add(new Customer() { CompanyName = "Max Cleaning Ltd.", FirstName = "", LastName = "" });
  customers.Add(new Customer() { CompanyName = "", FirstName = "Robin", LastName = "Robinson" });
  customers.Add(new Customer() { CompanyName = "Randomnezz Ltd.", FirstName = "", LastName = "" });
  // like 997 more (?) - we could actually use a for loop, haha
  ProcessCustomers(customers);
}

Keep in mind, that this is a basic example , usually I would of course prefer using some kind of async things. As this is no production code, etc. and just a context for showing the actual problem, I’ll leave it like that. So let’s continue with the actual point!

Right now, imagine that the form is loading and it will call the code attached as handler called „Form1_Load“. Inside of it, we are adding some dummy data and start processing it by calling the corresponding function „ProcessCustomers“. At first everything works pretty well, no worries so far. But as we are going to like customer „533“, there suddenly is an error being thrown – damn.

Usually we could think like „well, no problem, the IDE will stop and tell us where we are“. Yeah, at first glance this seems to work right, but not, if this data isn’t dummy data. That could probably mean, that we actually parsed/read a lot of useless data before. Maybe this useless data wouldn’t help us checking where we are right now and therefore not being able to find the dataset being the problem.

Counter / index to the rescue – no?

Well, beginners could (and believe me, as a mentor and freelance developer I almost saw everything) actually try to do something like this:

// leave everything else as it is

private void ProcessCustomers(List<Customer> customers)
{
  foreach (var customer in customers) {
    // hmm, which customer (index) is it
    var processingIndex = customers.IndexOf(customer);
    ProcessCustomer(customer);
  }
}

I mean I didn’t like look at the compiled IL code for the „IndexOf“ function (whether there is some kind of optmized hashmap in the background etc.), but.. Seeing this I’m thinking about: Well, does this „IndexOf“ thing really go through each element in each loop iteration – again!? To find the matching element and therefore finding out the corresponding index? I would think, that on each iteration, it’s going through each element and it’s comparing the equality by reference of objects.

Imagine having 50.000 datasets, being at the 49.999th iteration (the body of the loop). He would actually need to go through each 49.999 again, just to find out „Hey, I’m at index no 49.999“? Well this doesn’t seem clean at all, and this is damn right!

The conclusion

So the conclusion here actually is: Just use a normal for loop, when you are in the need of some kind of counter / indexer anyways. Alternatively you could initialize some kind of iteration variable outside the for each loop. Like this, you would increment it during iteration – but this doesn’t seem right as well..

// leave everything else as it is

private void ProcessCustomers(List<Customer> customers)
{
  foreach (var i = 0; i < customers.Count; i++) {
    // this is the iteration var "i" now
    // var processingIndex = ...;
    Debug.WriteLine($"I'm currently processing Customer at index {i}");
    ProcessCustomer(customer);
  }
}

When in the need of modifying while iterating

Now this is one of my favourite and tricky examples where I saw a lot of beginners struggling with (including myself of course 😂). So imagine thinking: „Well, np, I got all of those basics straight – I’m going to build my own chat client with a chatserver“. You started building your nicely architectured TCP server and a client which is able to actually connect – yay. What could possibly go wrong?

So there is one basic thing everyone thinks about when designing something like a chatserver (or a server in general). It’s keeping track of the connected clients. Maybe you are even using some kind of room-system in your app, nice! You are probably doing something like this here:

public class ChatServer
{

  // some listener _listener..

  // a constructor..

  protected List<ChatClient> _connectedClients;

  public bool IsRunning { get; protected set;}

  // some other stuff..
  public async void Run()
  {
    while (IsRunning)
    {
      // accept a new TCP client
      var tcpClient = await _listener.AcceptClientAsync();

      // create a custom class with more information
      var client = new ChatClient(tcpClient);

      // do some authentication

      // whatever..

      _connectedClients.Add(client);      
    }
  }

}

I’ll just remove on disconnect / kick – no?

Maybe it works perfectly fine for now, but later, when theres actually some sort of banning, disconnection handling and much more, it can get tricky. Usually you would try it in this manner (take care of this code being written out of my mind more in a pseudo manner):

public class ChatServer
{
  // same as before, but with some kind of disconnect event being raised
  // and some "broadcast" mechanism running / being called
  // no paket fragmentation used for this example, just a simple string message..

  public async Task BroadcastMessage(ChatClient from, string message)
  {
    foreach (var client in _connectedClients) {
      if (client.Id == from.Id)
      {
        await SendClientMessageAsync(client, message);
      }
    }
  }

  public async Task SendClientMessageAsync(ChatClient client, string message)
  {
    // sending the message somehow..
  }

  protected virtual void OnClientDisconnected(ClientEventArgs e)
  {
    // remove the client from the connected client collection
    // HERES THE CATCH!
    _connectedClients.Remove(e.Client);
  }

  public event EventHandler<ClientEventArgs>? ClientDisconnected;

}

The conclusion

So trying to make it work like this will essentially fail. Think about what’s happening if someone disconnects, while you are iterating inside the broadcasting method? This would raise an error, because you can’t just remove items while iterating through the collection. This mostly counts for some other languages as well – FYI, so it’s not a C# For Each only thingy.

Quick Examples – C# For Each

Short version without curly braces (only one statement possible!):

foreach (var item in items)
    Debug.Write(item);

Looping through each char of a string:

var name = "Robert";
foreach (var character in name) {
  Debug.Write(character);
}
Debug.WriteLine("");

Going through each button of the search field (a GroupBox here) of a form. If you want to go through each button of a form itself, just omit the „GroupBox1“:

foreach (var btn in GroupBox1.Controls.OfType<Button>()) {
  MessageBox.Show(btn.Text);
}

Getting through each string inside a ListBox (obviously filled with strings..)

var lb = new ListBox();
lb.Items.Add("Test");
lb.Items.Add("One");
lb.Items.Add("Two");
foreach (var name in lb.Items)
{
    // or explicitly cast it as string with like the Items.Cast function
    // see below for an example
    Debug.WriteLine(name.ToString());
}

Reiterating each even number returned by a helper function:

private IEnumerable<int> EvenNumbersBetween(int start, int end)
{
    for (var i = start; i <= end; i++)
    {
        if (i % 2 == 0)
            yield return i;
    }
}

foreach (var number in EvenNumbersBetween(1, 9))
{
    Debug.WriteLine(number);
}

Iterating through each (customer object) Item inside a ListBox:

public class Customer
{

    public string CompanyName { get; set; }

}
// take a look below to create a list of customers..
yourListBox.DataSource = yourListWithCustomers;
foreach (var customer in yourListBox.Items.Cast<Customer>())
{
    Debug.WriteLine(customer.CompanyName);
}

Going through each customer returned by a function

private IEnumerable<Customer> GetCustomers()
{
  var customers = new List<Customer>();
  customers.Add(new Customer() { CompanyName = "Company Ltd." });
  customers.Add(new Customer() { CompanyName = "Second Company Ltd." });
  customers.Add(new Customer() { CompanyName = "Another Company Ltd." });
  return customers;
}

foreach (var customer in GetCustomers()) {
  Debug.WriteLine(customer.CompanyName);
}

Related posts

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert