Click here to Skip to main content
15,892,059 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,
I write the following code:
#include "stdafx.h"

using namespace System;
using namespace System::Collections::Generic;

int main(array<System::String ^> ^args)
{
    array<String^>^ arr = gcnew array<String^>
    int i = 0;
 
    arr->SetValue("a", 0);
    arr->SetValue("b", 1);
    for each(String^% s in arr)
        s = i++.ToString();   //change elements in array
    for each(String^% s in arr)	           
        Console::WriteLine(L"{0}", s);

    List<String^>^ list= (gcnew List<String^>());
    list->Add("a");
    list->Add("b");
    for each(String^% s in list)    //change elements in List
	s=i.ToString();
    for each(String^% s in list)  
	Console::WriteLine(L"{0}", s);

    Console::ReadLine();
    return 0;
}


The output is:
0
1
a
b

I tried to change all elements in arr and list by the same way,
but got different results. I don't understand why the elements in arr are changed but not in list. Could someone explain it to me?
Thanks.
Posted

Interesting question.

wrote:
I don't understand why the elements in arr are changed but not in list. Could someone explain it to me?


To understand why the results are different, you need to understand what is happening when foreach is compiled. Compiler translates foreach depending on it's usage.

  • When foreach is used to iterate over an array, compiler compiles it into normal for loop.
  • When the type is not an array, compiler checks for GetEnumerator method and use it. The enumerator object returned by GetEnumerator method will be used for the processing..
Considering the above facts, your code for changing elements in an array compiles as a normal for loop and changing elements in list compiles as(written on this editor directly).
C++
List<String^>^::Enumerator^ enumerator = list->GetEnumerator();
while(true)
{
   if(!enumerator->MoveNext())
   {
      break;
   }
   String^ str = enumerator.Current; // str will be a different object with same value
   str = /* */ // Your new value assignment will come here
}
So whatever object you are changing is a copy of real object available in the list. Hence the changes won't be seen.

However, I am surprised to see the code compiles on C++/CLI. In C#, changing a foreach variable will yield into an error.

Hope that helps.
 
Share this answer
 
Try changing your "for each" loops to regular "for" loops. I'm not sure about C++/CLI, but I know changing the elements being iterated in a "for each" loop in C# will throw an exception.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900