Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is The Iteration Variable in a C# foreach statement read-only?

As I understand it, C#'s foreach iteration variable is immutable.

Which means I can't modify the iterator like this:

foreach (Position Location in Map) {      //We want to fudge the position to hide the exact coordinates      Location = Location + Random();     //Compiler Error       Plot(Location); } 

I can't modify the iterator variable directly and instead, I have to use a for loop

for (int i = 0; i < Map.Count; i++) {      Position Location = Map[i];      Location = Location + Random();       Plot(Location);              i = Location; } 

Coming from a C++ background, I see foreach as an alternative to the for loop. But with the above restriction, I usually fallback to using the for loop.

I'm curious, what is the rationale behind making the iterator immutable?


Edit:

This question is more of a curiousity question and not as a coding question. I appreciated the coding answers but I can't mark them as answers.

Also, the example above was over-simplified. Here is a C++ example of what I want to do:

// The game's rules:  //   - The "Laser Of Death (tm)" moves around the game board from the //     start area (index 0) until the end area (index BoardSize) //   - If the Laser hits a teleporter, destroy that teleporter on the //     board and move the Laser to the square where the teleporter  //     points to //   - If the Laser hits a player, deal 15 damage and stop the laser.  for (int i = 0; i < BoardSize; i++) {     if (GetItem(Board[i]) == Teleporter)     {         TeleportSquare = GetTeleportSquare(Board[i]);         SetItem(Board[i], FreeSpace);         i = TeleportSquare;     }      if (GetItem(Board[i]) == Player)     {         Player.Life -= 15;         break;     } } 

I can't do the above in C#'s foreach because the iterator i is immutable. I think (correct me if I'm wrong), this is specific to the design of foreach in languages.

I'm interested in why the foreach iterator is immutable.

like image 555
MrValdez Avatar asked Apr 22 '09 09:04

MrValdez


People also ask

What does iteration variable do?

The iterator (loop) variable is the variable which stores a portion of the iterable when the for loop is being executed. Each time the loop iterates, the value of the iterator variable will change to a different portion of the iterable.

What is iteration in C?

What is Looping ? • The looping can be defined as repeating the same process multiple times until a specific condition satisfies. It is known as iteration also. There are three types of loops used in the C language.

Why do we use for loop in C?

A for loop is a repetition control structure that allows you to efficiently write a loop that needs to execute a specific number of times.

Which loop is used for iteration?

In computer science, a for-loop (or simply for loop) is a control flow statement for specifying iteration, which allows code to be executed repeatedly.


1 Answers

Lets start out with a silly but illustrative example:

Object o = 15; o = "apples"; 

At no point do we get the impression that we just turned the number 15 into a string of apples. We know that o is simply a pointer. Now lets do this in iterator form.

int[] nums = { 15, 16, 17 };  foreach (Object o in nums) {      o = "apples"; } 

Again, this really accomplishes nothing. Or at least it would accomplish nothing were it to compile. It certainly wouldn't insert our string into the int array -- that's not allowed, and we know that o is just a pointer anyway.

Let's take your example:

foreach (Position Location in Map) {      //We want to fudge the position to hide the exact coordinates      Location = Location + Random();     //Compiler Error       Plot(Location); } 

Were this to compile, the Location in your example stars out referring to a value in Map, but then you change it to refer to a new Position (implicitly created by the addition operator). Functionally it's equivalent to this (which DOES compile):

foreach (Position Location in Map) {      //We want to fudge the position to hide the exact coordinates      Position Location2 = Location + Random();     //No more Error       Plot(Location2); } 

So, why does Microsoft prohibit you from re-assigning the pointer used for iteration? Clarity for one thing -- you don't want people assigning to it thinking they've changed your position within the loop. Ease of implementation for another: The variable might hide some internal logic indicating the state of the loop in progress.

But more importantly, there is no reason for you to want to assign to it. It represents the current element of the looping sequence. Assigning a value to it breaks the "Single Responsibility Principle" or Curly's Law if you follow Coding Horror. A variable should mean one thing only.

like image 109
tylerl Avatar answered Sep 28 '22 08:09

tylerl