• 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

    • I'm sure Denmark would stand to lose a lot if US consumers stopped buying Danish products, whether that's Lurpak butter or hi-fi equipment.
    • JD Vance will be the next President. Who've the Democrats got? Harris again? lol....
    • Microsoft Edge gets new password feature and security fixes by Taras Buria Microsoft has released a new update for the Edge browser in the Stable Channel. Version 137.0.3296.83 introduces a new password feature and fixes security vulnerabilities to make your browsing experience safer. Starting with new features, Microsoft Edge 137 now supports Secure Password Deployment. Microsoft recently announced this for IT admins, allowing them to share encrypted passwords with user groups. This service lets users log into websites without seeing their passwords, thus enhancing the organization's security. You can read more about Microsoft Edge Secure Password Deployment in our recent article here. Security updates in Microsoft Edge 137.0.3296.83 include two fixes for Chromium vulnerabilities: CVE-2025-5958: Use after free in Media in Google Chrome prior to 137.0.7151.103 allowed a remote attacker to potentially exploit heap corruption via a crafted HTML page. (Chromium security severity: High) CVE-2025-5959: Type Confusion in V8 in Google Chrome prior to 137.0.7151.103 allowed a remote attacker to execute arbitrary code inside a sandbox via a crafted HTML page. (Chromium security severity: High) You can update Microsoft Edge to the latest version by heading to edge://settings/help. The browser can also update itself automatically in the background and apply updates between restarts. In case you missed it, Microsoft released Edge 137 by the end of May. The update deprecated quite a lot of existing features, including Wallet, Image Editor, Image Hover, Mini menu, and Video Super Resolution. It also introduced Web Content Filtering and enhancements for the picture-in-picture player and Find on Page in Microsoft Edge for Business. The next feature update for Microsoft Edge, version 138, is expected on the week of June 26, 2025, as part of the standard four-week release cadence.
    • Microsoft commits to upskill 1 million UK workers in AI this year by Paul Hill Microsoft has partnered with the UK government in the latter’s ambitious plan to train 7.5 million workers in AI skills over the next five years. Specifically, Microsoft has committed to upskilling 1 million of those workers by the end of this year. This represents a significant portion of the overall target and within a very short timeframe. The education drive by Microsoft builds on its previous “Get On” program, which has given 1.5 million people basic digital skills. The effort to train up 1 million British workers in AI is part of Microsoft’s broader £2.5 billion investment in UK AI infrastructure. Ensuring workers have the skills to leverage AI tools is important. Microsoft CEO UK Darren Hardman said recently that two-thirds of business people wouldn’t hire someone lacking AI skills, showing just how vital it is to get people’s skills up to date. Microsoft's approach to AI skills development Microsoft has several platforms to offer AI training, including Microsoft Learn, AI Skills Navigator, and through partnerships with non-profit organisations such as Catch22 in the UK. Its educational materials cover everything from the basics of generative AI to helping you prepare for advanced roles like being an AI engineer. With Catch22, Microsoft helps to train people who face various challenges to getting tech skills, including gender and ethnicity barriers, homelessness, mental health issues, school exclusion and disability. Microsoft is also trying to get more women into tech fields through programmes like TechHer, where it has trained thousands of women across UK government departments. Many of the courses that Microsoft offers come complete with certificates that you can show off on your CV when applying for a job to impress potential employers and land a job. Who else is partnering with the UK government? While Microsoft is playing a massive role in the government’s plans, it’s not the only big tech giant helping out. The firms that have partnered with the government are: Accenture, Amazon, Barclays, BT, Google, IBM, Intuit, Microsoft, Sage, SAS, and Salesforce. While all of these firms are helping to train workers, Microsoft’s planned efforts are the most notable. This initiative by the government will help the country brace for the changes AI is expected to bring to the economy. In April, the United Nations said that AI will affect 40% of all jobs, so being ready is a must.
    • Microsoft has an update on Exchange Online Basic Auth removal for Office 365 by Sayan Sen Back in 2022, Microsoft announced the retirement of Basic Authentication as it was moving to modern OAuth 2.0 token-based authentication. The reason was simple, to move away from such simple username-password authentication to more secure sign-ins. While Microsoft had previously planned to "permanently remove support for Basic authentication with Client Submission (SMTP AUTH) in September 2025", the company has now updated this timeline, adding a final delay. Perhaps this was on the cards given that Microsoft recently extended Basic Auth support for High Volume Email to 2028. On the Microsoft 365 Admin Center, a new message has been posted that details the changes regarding SMTP (Simple Mail Transfer Protocol) AUTH Client Submission. The message says: Thus, starting March 1, 2026, Exchange Online will begin phasing out Basic authentication for sending emails via SMTP AUTH. At first, fewer attempts will be blocked, but by April 30, 2026, this older method will be fully disabled. After that, any apps or devices that want to send email this way will need to use OAuth. The message further adds how admins can proceed with the changes in case OAuth is not supported: Users who have access to the M365 Admin Center can view the message under ID MC786329.
  • Recent Achievements

    • Week One Done
      LagFighterZ earned a badge
      Week One Done
    • First Post
      ThatGuyOnline earned a badge
      First Post
    • One Month Later
      5i3zi1 earned a badge
      One Month Later
    • Week One Done
      5i3zi1 earned a badge
      Week One Done
    • Week One Done
      julien02 earned a badge
      Week One Done
  • Popular Contributors

    1. 1
      +primortal
      540
    2. 2
      ATLien_0
      224
    3. 3
      +FloatingFatMan
      160
    4. 4
      Michael Scrip
      115
    5. 5
      +Edouard
      91
  • Tell a friend

    Love Neowin? Tell a friend!