Alex Rivera | Logout

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

Asked 2009-04-22T09:48:21.363
43

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

Edit
Report

1 Answer

10

I think its artificial limitation, no really need to do it. To prove the point, take this code into consideration, and a possible solution to your problem. The problem is to assign, but internal changes of objects don't present a problem:

using System;
using System.Collections.Generic;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {

            List<MyObject> colection =new List<MyObject>{ new MyObject{ id=1, Name="obj1" }, 
                                                    new MyObject{ id=2, Name="obj2"} };

            foreach (MyObject b in colection)
            {
             // b += 3;     //Doesn't work
                b.Add(3);   //Works
            }
        }

        class MyObject
        {
            public static MyObject operator +(MyObject b1, int b2)
            {
                return new MyObject { id = b1.id + b2, Name = b1.Name };
            }

          public void Add(int b2)
          {
              this.id += b2;
          }
            public string Name;
            public int id;
        }
    }
}

I didn't know about this phenomena, because I was always modifying the objects the way I described.

answered 2009-04-22T11:35:54.817

Your Answer