Something to watch out for when using for each

Look at the following code :

int main()
{
    array<String^>^ strarr = gcnew array<String^>(5);
    int count = 0;
    for each(String^ s in strarr)
        s = gcnew String(count++.ToString());
    for each(String^ s in strarr)
        Console::WriteLine(s);
    return 0;
}

If you expect it to output 0, 1, 2, 3 and 4 on separate lines, you are going to be disappointed, because it simply prints 5 blank strings. So what happened?

Look at this specific line : for each(String^ s in strarr). s is a local handle that is a copy of the current iterated element in strarr. The operative word there is “copy”. Thus, when you gcnew the String, you are assigning it to this local handle and not to the array element.

The right way to write that for each loop is :

for each(String^% s in strarr)

Note that you don’t have to do this for the second loop since you are only reading the array.

9 thoughts on “Something to watch out for when using for each”

  1. I mean, you cannot do the same thing in C# using it’s version of foreach, simply because you can’t use the ref keyword in a foreach. For example, you cannot go

    foreach(ref string str in strarray) // nope!

    Obviously there are workarounds, just kind of interesting that C++/CLI’s for each can do it but C# cannot.

  2. Ah, okay, thanks for the info, Judah πŸ™‚

    >>Obviously there are workarounds,

    May I know what they are? (unless you mean using a regular for-loop)

Leave a Reply