• 0

[C#] Assign values in dictionary


Question

Hi, I have say a

Dictionary<Color, int> myDict;

And I want to do this:

foreach (var kvPair in myDict) {
     kvPair.Value = 0; // not necessarily always 0, could be calculated per-value, whatever
}

But this triggers a compiler error:

Property or indexer 'System.Collections.Generic.KeyValuePair<Color,int>.Value' cannot be assigned to -- it is read only

How can I do this?

Link to comment
https://www.neowin.net/forum/topic/871176-c-assign-values-in-dictionary/
Share on other sites

14 answers to this question

Recommended Posts

  • 0

You can't alter a collection in a foreach loop, convert it to a normal for loop.

*Nevermind* that would be adding/removing the collection item...

for(int i=0; i< myDict.Values; i++)

{

kvPair....

}

  • 0
  On 01/02/2010 at 02:36, Calum said:

Does it work if you try the following?

foreach (KeyValuePair kvPair in myDict) {
     kvPair.Value = 0; // not necessarily always 0, could be calculated per-value, whatever
}

C# will infer System.Collections.Generic.KeyValuePair if you put var, so it's equivalent.

Actually I know of a way, but it's ugly and wastes CPU cycles:

foreach (Color color in Enum.GetValues(typeof(Color))) {
     myDict[color] = 0;
}

I'm wondering if I should use another container or if there's a more idiomatic way.

  • 0
  On 01/02/2010 at 02:41, Dr_Asik said:

C# will infer System.Collections.Generic.KeyValuePair if you put var, so it's equivalent.

Actually I know of a way, but it's ugly and wastes CPU cycles:

foreach (Color color in Enum.GetValues(typeof(Color))) {
     myDict[color] = 0;
}

I'm wondering if I should use another container or if there's a more idiomatic way.

Not using KVPs I don't think, since KVP objects are basically read-only once they have been instantiated for reasons which are beyond me (Why make the value member read-only?). I was going suggest using a SortedDictionary object since they're implemented as a binary tree and you could use a depth-first search to basically loop through the whole collection, but the OrderedDictionary object doesn't provide the facility to do it.

I was also going to suggest foreach'ing through the "Keys" collection, but I suspect that that would be less efficient than what you suggested.

I would say that it would be easier just to take the performance hit in this case, since the lookup time for a Dictionary is close to O(1) since its implemented as a hash table. Unless its a completely performance critical piece of code, in which case you might need to look into some of the other collection types.

  • 0

As previously stated, KeyValuePair<K, V> is a structure (read: not class) with read-only properties. The reasons behind this is that structures perform better when they are immutable. It's better to instantiate a new instance of a KeyValuePair<K, V> then to try and modify it's content. That being said, you can't modify an enumeration, this is also be design, so:

foreach (var pair in myDict) {
  pair.Value = 0; // This will fail because of read-only properties.
}

foreach (var pair in myDict) {
  pair = new KeyValuePair&lt;...&gt; // Won't work as you are modifying a read-only variable.
}

Whereas:

foreach (Color key in myDict.Keys) {
  myDict[key] = 0; // Make the modification here
}

... should work, as the you are enumerating over a collection of keys, not KeyValuePair<Color, int> items, and can modify the contents of the dictionary correctly.

  • Like 3
  • 0
  On 01/02/2010 at 09:18, Antaris said:

As previously stated, KeyValuePair<K, V> is a structure (read: not class) with read-only properties. The reasons behind this is that structures perform better when they are immutable.

And now I know! Thanks Antaris, have some Rep! :D

  • 0
  On 01/02/2010 at 09:18, Antaris said:

Whereas:

foreach (Color key in myDict.Keys) {
  myDict[key] = 0; // Make the modification here
}

... should work, as the you are enumerating over a collection of keys, not KeyValuePair<Color, int> items, and can modify the contents of the dictionary correctly.

Well, I'm afraid it doesn't, after testing it, I get a runtime error on the second iteration saying it cannot continue because the collection has been modified. So, back to iterating over Enum.GetValues for now. :unsure:
  • 0
  On 01/02/2010 at 18:28, Dr_Asik said:

Well, I'm afraid it doesn't, after testing it, I get a runtime error on the second iteration saying it cannot continue because the collection has been modified. So, back to iterating over Enum.GetValues for now. :unsure:

You get an error because the Keys collection is invalid after changing the value. Now, you can get around this by iterating over a list which temporarily holds the keys. That way, you get a List<Color> which contains all keys at that certain point. This list is not managed by the Dictionary and therefore won't be invalidated when you make changes to the Dictionary.

foreach (Color key in myDict.Keys.ToList()) {
    myDict[key] = 0; // Make the modification here
}

This appears to be the fastest and safest way to do this, so go and make good use of it. :)

  • 0
  On 01/02/2010 at 18:43, Calculator said:

foreach (Color key in myDict.Keys.ToList()) {
    myDict[key] = 0; // Make the modification here
}

This appears to be the fastest and safest way to do this, so go and make good use of it. :)

So are the keys cached in an array (or equivalent) then? I figured that it wouldn't be, whereas the enum values would just be known, making it less safe, but faster. Am I way off then?

  • 0
  On 01/02/2010 at 19:04, Majesticmerc said:

So are the keys cached in an array (or equivalent) then? I figured that it wouldn't be, whereas the enum values would just be known, making it less safe, but faster. Am I way off then?

Enum.GetValues() creates an array, while myDict.Keys.ToList() creates a List. Either way, allocation of a container every time. I don't like either, but it seems there's no other way.

It's a bit silly, but anyhow if I was writing for ideal performance I'd be using C++ so I guess it's tolerable.

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • And of course that battery is the thing I'll need to replace sooner or later. It's starting to act a little flaky in its charge meter and that glue is just annoying to deal with. No need for it to be glued in place.
    • I'll say you are 50% correct. On the content side, yes, YouTube's content is basically free. Some might point out that they share ad revenue with creators, but I'll side with you saying that doesn't count. If the ad isn't viewed, the creator gets nothing from YouTube, so viewing the content is net-zero for everyone, not net-negative. The other half of the equation is the platform costs. Both YouTube and Netflix have a cost to provide their service. Netflix bakes the cost into their plans, which can be plainly seen by the different resolutions offered at different tiers, which is a pure platform cost. As you pointed out, YouTube doesn't pay licensing fees, so their entire cost structure is the platform. Using that platform without watching the ads (or paying for premium) is not net-zero like above, in this case it is net-negative. You consumed resources on YouTube systems that YouTube very clearly is not offering for free, they expect compensation in the form of viewing ads or paying for premium. TLDR, the company offering the service sets the price, either in currency or ad viewing. As the consumer, you can choose to make that agreement or not. Consuming the service without paying the price is not being offered.
    • Exactly that, in my case it doesn't work at all!
    • Last chance to download The Cybersecurity Control Playbook (worth $100) for free by Steven Parker Claim your complimentary eBook worth $100 for free, before the offer ends on June 4. Implement effective cybersecurity measures for all organizations Cybersecurity is one of the central concerns of our digital age. In an increasingly connected world, protecting sensitive data, maintaining system integrity, and ensuring privacy have never been more important. The Cybersecurity Control Playbook offers a step-by-step guide for implementing cybersecurity controls that will protect businesses and prepare them to compete in an overwhelmingly networked landscape. With balanced coverage of both foundational and advanced topics, and concrete examples throughout, this is a must-own resource for professionals looking to keep their businesses safe and secure. Readers will also find: Clear, jargon-free language that makes it accessible to a wide range of readers An introduction to developing, deploying, monitoring, testing, and retiring controls and control frameworks across large, medium, and small enterprises A system for identifying, prioritizing, and managing cyber risks based on the MITRE ATT&CK framework, with additional coverage of other key cybersecurity frameworks The Cybersecurity Control Playbook is ideal for cybersecurity practitioners, IT professionals, and security managers who are responsible for implementing and managing cybersecurity strategies in their organizations. How to get it Please ensure you read the terms and conditions to claim this offer. Complete and verifiable information is required in order to receive this free offer. If you have previously made use of these free offers, you will not need to re-register. While supplies last! Download The Cybersecurity Control Playbook (worth $100) for free Offered by Wiley, view other free resources The below offers are also available for free in exchange for your (work) email: The Cybersecurity Control Playbook ($100 Value) FREE – Expires today 6/4 The Embedded Linux Security Handbook ($31.99 Value) FREE – Expires today 6/4 Teach Yourself VISUALLY Microsoft 365, 2nd Edition ($20 Value) FREE – Expires 6/4 Winxvideo AI V3.0 Lifetime License for PC ($69.95 Valued) FREE – Expires 6/8 Aiarty Image Enhancer for PC/Mac ($85 Value) FREE – Expires 6/8 Solutions Architect's Handbook, Third Edition ($42.99 Value) FREE – Expires 6/10 AI and Innovation ($21 Value) FREE – Expires 6/11 Macxvideo AI ($39.95 Value) Free for a Limited Time – Expires 6/22 The Ultimate Linux Newbie Guide – Featured Free content Python Notes for Professionals – Featured Free content Learn Linux in 5 Days – Featured Free content Quick Reference Guide for Cybersecurity – Featured Free content We post these because we earn commission on each lead so as not to rely solely on advertising, which many of our readers block. It all helps toward paying staff reporters, servers and hosting costs. Other ways to support Neowin The above deal not doing it for you, but still want to help? Check out the links below. Check out our partner software in the Neowin Store Buy a T-shirt at Neowin's Threadsquad Subscribe to Neowin - for $14 a year, or $28 a year for an ad-free experience Disclosure: An account at Neowin Deals is required to participate in any deals powered by our affiliate, StackCommerce. For a full description of StackCommerce's privacy guidelines, go here. Neowin benefits from shared revenue of each sale made through the branded deals site.
    • I use Firefox for all the reasons already mentioned above and I also use Edge mainly because I like the snappiness of it. It does seem snappier then Firefox to me. I figure I might as well have 1 of each type browser engine. I probably won't use Edge as much once they follow in Googles footsteps of killing my ad blocker. I play around with several other browsers usually when I see an updated story on them here just to see if they can persuade me to stick with them, but they usually don't. Have never figured out what it is about Google Chrome that makes others like it so much? Heck, it isn't even smart enough to give you an option to alphabetize your bookmarks!
  • Recent Achievements

    • Week One Done
      mywakehealth earned a badge
      Week One Done
    • Dedicated
      jbatch earned a badge
      Dedicated
    • Week One Done
      Leonard grant earned a badge
      Week One Done
    • One Month Later
      portacnb1 earned a badge
      One Month Later
    • Week One Done
      portacnb1 earned a badge
      Week One Done
  • Popular Contributors

    1. 1
      +primortal
      295
    2. 2
      snowy owl
      162
    3. 3
      +FloatingFatMan
      156
    4. 4
      ATLien_0
      143
    5. 5
      Xenon
      125
  • Tell a friend

    Love Neowin? Tell a friend!