c#: Changing a value in a dictionary in a foreach

1 comment

I was trying to loop through a dictionary,

update it's value if a certain condition was met,

if not remove the item from the dictionary.

(Seems I have done something lke this before, but that's why I blog it, so I can remember next time… :))

Here's my first attempt:

        private void FindEditedFieldsNotWorking(Dictionary<string, string> dictionary, Control ctrl)

        {

            foreach (KeyValuePair<string,string> kvp in dictionary)

            {

                CheckBox c = ctrl.Controls["chk" + kvp.Key] as CheckBox;

                if (c != null && c.Checked)

                {

                    dictionary[kvp.Key] = ctrl.Controls[kvp.Key].Text;

                }

                else

                    dictionary.Remove(kvp.Key);

            }

        }

It compiles ok and seems ok.

Might have a misgiving with removing the item in a loop, but hey it's worth a shot..

When running this I got an exception something like

"Collection was modified; enumeration operation may not execute."

My first thought was that my dictionary.Remove was the culprit, so I put a breakpoint there.

But that was not the case (although that is not supported either in this loop)

It seems that I can't actually change the freakin' value within my foreach loop…!

So I tried the same but this time using just the keys in the loop:

         private void FindEditedFieldsNotWorkingEither(Dictionary<string, string> dictionary, Control ctrl)

        {

            foreach (string Key in dictionary.Keys)

            {

                CheckBox c = ctrl.Controls["chk" + Key] as CheckBox;

                if (c != null && c.Checked)

                {

                    dictionary[Key] = ctrl.Controls[Key].Text;

                }

                else

                    dictionary.Remove(Key);

            }

        }

Still no go, same error.

Eventually I read a little bit about this using google and found that I couldn't do any changes while enumerating.

Here are some links I used:

http://stackoverflow.com/questions/1070766/editing-dictionary-values-in-a-foreach-loop

http://stackoverflow.com/questions/1562729/why-cant-we-change-values-of-a-dictionary-while-enumerating-its-keys

Seems like a bad design decision has made this a problem for many ppl.

The incling is probably the implisit add functionality when doing dict[key]=value; when key is not existing.

Anyways we have to get around this somehow.

The solution I thought was nicest when I couldn't use the "logic" solution is:

.Net 2.0

        private void FindEditedFieldsWorking(Dictionary<string, string> dictionary, Control ctrl)

        {

            List<string> keys = new List<string>(dictionary.Keys);

            foreach (string key in keys)

            {

                CheckBox c = ctrl.Controls["chk" + key] as CheckBox;

                if (c != null && c.Checked)

                {

                    dictionary[key] = ctrl.Controls[key].Text;

                }

                else

                    dictionary.Remove(key);

            }

        }

Almost as nice as the first version, and with the added premium that dictionary.Remove won't be a problem.

Or if you're running .Net 3.0 or higher you could just do this:

        private void FindEditedFieldsWorking(Dictionary<string, string> dictionary, Control ctrl)

        {

          

            foreach (var key in dictionary.Keys.ToList())

            {

                CheckBox c = ctrl.Controls["chk" + key] as CheckBox;

                if (c != null && c.Checked)

                {

                    dictionary[key] = ctrl.Controls[key].Text;

                }

                else

                    dictionary.Remove(key);

            }

        }

where the ToList does the same as our 2.0 solution, namely creating a temp list to hold the keys.

Nice solution on a not so nice problem.

Hope this helps someone,

it will help me next time anyways :)

Regards

Henri Merkesdal

MERIT

Posted via email from Henris blogg

1 comment :

  1. Hi, Great.. Tutorial is just awesome..It is really helpful for a newbie like me.. I am a regular follower of your blog. Really very informative post you shared here. Kindly keep blogging. If anyone wants to become a .Net developer learn from Dot Net Training in Chennai. or learn thru Dot Net Training in Chennai. Nowadays Dot Net has tons of job opportunities on various vertical industry.
    or Javascript Training in Chennai. Nowadays JavaScript has tons of job opportunities on various vertical industry.

    ReplyDelete