Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. c# complex dictionary: can modify value in for-loop: thought you couldn't do that

c# complex dictionary: can modify value in for-loop: thought you couldn't do that

Scheduled Pinned Locked Moved C#
csharplinqtestingbeta-testingfunctional
5 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    BillWoodruff
    wrote on last edited by
    #1

    I don't know which is better, or worse, having code that works for reasons you don't understand, or having code that breaks for reasons you don't understand :) Today I was testing the use of a complex dictionary of the form:

    public Dictionary, List>

    I was surprised to find that I could iterate ... in a lambda expression passed as the argument to a Func ... over the List of T3 with a 'for loop and change the values without getting the "attempt to modify ..." error. Example:

    Test = new Dictionary<KeyValuePair<string, int>, List<int>>
    {
    {new KeyValuePair<string,int>("hello",1),
    new List<int> {1,2,3,4}},

    {new KeyValuePair<string,int>("goodbye",2),
    new List<int> {6,7,8,9}}
    };

    foreach (var kvp in Test)
    {
    for (int i = 0; i < kvp.Value.Count; i++)
    {
    kvp.Value[i] *= 10;
    }
    }

    Of course, you can never change the value of the Key or Value of the KeyValuePair ... they have no setters, but, I was surprised I could modify the value in this kind of loop ... I assume I could always modify the value outside of a loop where I iterated across the structure. So, why don't this break ? My memory includes the use of various yogic contortions a few years ago to avoid the "can't modify collection" error. Come to think on it: I distrust code that works for reasons I don't understand more than ... the other :) thanks, Bill

    «There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008

    OriginalGriffO 1 Reply Last reply
    0
    • B BillWoodruff

      I don't know which is better, or worse, having code that works for reasons you don't understand, or having code that breaks for reasons you don't understand :) Today I was testing the use of a complex dictionary of the form:

      public Dictionary, List>

      I was surprised to find that I could iterate ... in a lambda expression passed as the argument to a Func ... over the List of T3 with a 'for loop and change the values without getting the "attempt to modify ..." error. Example:

      Test = new Dictionary<KeyValuePair<string, int>, List<int>>
      {
      {new KeyValuePair<string,int>("hello",1),
      new List<int> {1,2,3,4}},

      {new KeyValuePair<string,int>("goodbye",2),
      new List<int> {6,7,8,9}}
      };

      foreach (var kvp in Test)
      {
      for (int i = 0; i < kvp.Value.Count; i++)
      {
      kvp.Value[i] *= 10;
      }
      }

      Of course, you can never change the value of the Key or Value of the KeyValuePair ... they have no setters, but, I was surprised I could modify the value in this kind of loop ... I assume I could always modify the value outside of a loop where I iterated across the structure. So, why don't this break ? My memory includes the use of various yogic contortions a few years ago to avoid the "can't modify collection" error. Come to think on it: I distrust code that works for reasons I don't understand more than ... the other :) thanks, Bill

      «There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008

      OriginalGriffO Offline
      OriginalGriffO Offline
      OriginalGriff
      wrote on last edited by
      #2

      It works because you aren't modifying anything the iterator needs to worry about: neither the key nor the value are being modified in any way (since they are a struct you can't change and a reference). You can modify the content of the object the reference "points" to very easily and legally inside the foreach, because you aren't trying to change the values in the collection you are iterating over.

      List<MyClass> list = new List<MyClass>();
      for (int i = 0; i < 5; i++)
      {
      MyClass mc = new MyClass() { s = i.ToString() };
      list.Add(mc);
      }
      foreach (MyClass mc in list)
      {
      mc.s = mc.s + " changed!";
      }
      foreach (MyClass mc in list)
      {
      Console.WriteLine(mc.s);
      }

      Will give you:

      0 changed!
      1 changed!
      2 changed!
      3 changed!
      4 changed!

      But obviously trying to change the actual value will give you a compilation error:

      foreach (MyClass mc in list)
      {
      mc = new MyClass() { s = mc.s + " Changed again!" };
      }

      Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...

      "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
      "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt

      B 1 Reply Last reply
      0
      • OriginalGriffO OriginalGriff

        It works because you aren't modifying anything the iterator needs to worry about: neither the key nor the value are being modified in any way (since they are a struct you can't change and a reference). You can modify the content of the object the reference "points" to very easily and legally inside the foreach, because you aren't trying to change the values in the collection you are iterating over.

        List<MyClass> list = new List<MyClass>();
        for (int i = 0; i < 5; i++)
        {
        MyClass mc = new MyClass() { s = i.ToString() };
        list.Add(mc);
        }
        foreach (MyClass mc in list)
        {
        mc.s = mc.s + " changed!";
        }
        foreach (MyClass mc in list)
        {
        Console.WriteLine(mc.s);
        }

        Will give you:

        0 changed!
        1 changed!
        2 changed!
        3 changed!
        4 changed!

        But obviously trying to change the actual value will give you a compilation error:

        foreach (MyClass mc in list)
        {
        mc = new MyClass() { s = mc.s + " Changed again!" };
        }

        Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...

        B Offline
        B Offline
        BillWoodruff
        wrote on last edited by
        #3

        Thanks Grif ! I don't know my trying to grok this slips off me brain like noodles slip off a spoon. These memories I have of using exotic means to modify collections to avoid error ... I believe one of the memories is of a technique you posted years ago ... something about iterating from end of the collection to the start. Alas, memory, unreliable companion as age ticks off my telomeres :) cheers, Bill

        «There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008

        OriginalGriffO Richard DeemingR 2 Replies Last reply
        0
        • B BillWoodruff

          Thanks Grif ! I don't know my trying to grok this slips off me brain like noodles slip off a spoon. These memories I have of using exotic means to modify collections to avoid error ... I believe one of the memories is of a technique you posted years ago ... something about iterating from end of the collection to the start. Alas, memory, unreliable companion as age ticks off my telomeres :) cheers, Bill

          «There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008

          OriginalGriffO Offline
          OriginalGriffO Offline
          OriginalGriff
          wrote on last edited by
          #4

          Off topic, but on subject - did your op get cancelled again?

          Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...

          "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
          "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt

          1 Reply Last reply
          0
          • B BillWoodruff

            Thanks Grif ! I don't know my trying to grok this slips off me brain like noodles slip off a spoon. These memories I have of using exotic means to modify collections to avoid error ... I believe one of the memories is of a technique you posted years ago ... something about iterating from end of the collection to the start. Alas, memory, unreliable companion as age ticks off my telomeres :) cheers, Bill

            «There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008

            Richard DeemingR Offline
            Richard DeemingR Offline
            Richard Deeming
            wrote on last edited by
            #5

            BillWoodruff wrote:

            something about iterating from end of the collection to the start.

            You usually do that if you're removing items from the collection within a for loop, and you don't want to skip any elements. :)


            "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

            "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups