Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# strange behaviour in foreach loop

Tags:

c#

loops

foreach

After a day of troubleshooting I've managed to condense the problem to this tiny piece of code. Could someone explain to me why this doesn't work? I expect [markets] to be 0 2 4 6, [city] [county] and [streets] to be 0 1 2 3 when the messagebox is shown.

        private void pieceoftestcode()
        {
            string[] county = new string[4];
            string[] city = new string[4];
            string[] markets = new string[4];
            string[] streets = new string[4];
            string[] items = new string[4] { "apple", "banana", "pineapple", "juice" };
            string[] value = new string[4];
            foreach (string item in items)
            {
                for (int i = 0; i <= 3; i++)
                {
                    if (item == "apple")
                        value[i] = (2 * i).ToString();
                    else
                        value[i] = i.ToString();
                }

                if (item == "apple")
                    markets = value;
                else if (item == "banana")
                    streets = value;
                else if (item == "pineapple")
                    county = value;
                else
                    city = value;
            }
            MessageBox.Show("test");
        }

I'm looping through items in a foreach loop. If the item is "apple", then I expect [value] to be 0 2 4 6. Initially [markets] is assigned 0 2 4 6. However, if I execute the code step by step, it appears that the second time that the foreachloop is executed, [markets] is being overwritten. Why is that? What am I doing wrong here? [markets] should not be assigned a value a second time once banana has hit right?

like image 888
Maarten Avatar asked Mar 31 '20 13:03

Maarten


Video Answer


1 Answers

You gradually end up with all of your various variables referencing the same array (value), with whatever values are written into that array by the last iteration being set.

There's a very similar way of writing this code that avoids the issue:

    private void pieceoftestcode()
    {
        string[] county = new string[4];
        string[] city = new string[4];
        string[] markets = new string[4];
        string[] streets = new string[4];
        string[] items = new string[4] { "apple", "banana", "pineapple", "juice" };
        string[] value;
        foreach (string item in items)
        {
            if (item == "apple")
                value = markets;
            else if (item == "banana")
                value = streets;
            else if (item == "pineapple")
                value = county;
            else
                value = city;
            for (int i = 0; i <= 3; i++)
            {
                if (item == "apple")
                    value[i] = (2 * i).ToString();
                else
                    value[i] = i.ToString();
            }


        }
        MessageBox.Show("test");
    }

Now, each time through the loop value get assigned a reference to a different array1 and so the for loop doesn't overwrite its previous efforts.


1Assuming items doesn't contain any duplicate items nor more than one non-apple, -banana or -pineapple item.

like image 152
Damien_The_Unbeliever Avatar answered Oct 13 '22 11:10

Damien_The_Unbeliever