• 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

    • "Linux, I gotta tell you, is the worst. I have never even heard about it, but everyone is talking about how it is the worst. Trump Office is a big, beautiful application, that will do, frankly, all the things very strongly."
    • WebSite-Watcher 2025 (25.4) by Razvan Serea WebSite-Watcher is a powerful yet simple website-monitoring tool, perfectly suited to the beginner and advanced user alike. If you can work with an email client, you can even work with WebSite-Watcher! The software places you in complete control over what gets checked, when it gets checked, and even how you are notified. WebSite-Watcher main features: Monitor web pages Monitor password protected pages Monitor forums for new postings and replies Monitor PDF/Word/Excel documents Monitor binary files Monitor local files Monitor RSS feeds, Newsgroups and local files Highlight changes in a page Powerful filter system to ignore unwanted content Many more features to stay up-to-date. Lots of other features: Additional actions when updates are detected - For example to play an alternative sound, send emails or open the changed page with another program. You configure the software to work the way you want. Powerful Plugin system - Bookmark checks can be enhanced with the integrated Plugin system. For example to monitor a page for a specific price and alert an update only if the price is less than USD 100. Plugins must be written in the programming language Basic. WebSite-Watcher contains an integrated development system, no other tools are required. Work with checked pages (Searches, Reports, etc.) - All monitored pages are saved to your hard drive. This allows you to quickly and simply open and view the monitored pages, search text in downloaded files and make reports... all without even having to be online. Archive pages permanently - Keep the information you need by archiving pages with our tool Local Website Archive. This can be done automatically via the bookmark properties or manually on demand. Synchronize bookmark files - Synchronize bookmarks between computers with the synchronize functionality. Backup and Restore - The integrated Backup/Restore feature allows you to backup and restore your settings, bookmarks and downloaded files into/from a zip archive. WebSite-Watcher 2025 (25.4) changelog: Workaround for a Windows bug that displays short flashing windows when checking bookmarks with the Chromium or Edge technology (this bug was introduced with one of the latest Windows updates and affects many software tools, including WebSite-Watcher). Highlight changes: Improvements for more exact highlights within paragraphs If a page uses CloudFront and cannot be monitored with the internal check technology, WebSite-Watcher will automatically use the Chromium technology Download Manager: files could not be downloaded after certain circumstances Download Manager: Improved file type detection based on the file content Dialup/Hangup re-implemented for better compatibility. This function is now based on rasdial.exe which is part of Windows. Plugins: the functions "Chr" and "Ord" work now with Unicode character codes The AutoBackup window is no longer displayed when WebSite-Watcher is minimized or in the tray bar Smaller fixes and improvements Download: WebSite-Watcher 2025 (25.4) | 148.0 MB (Shareware) View: WebSite-Watcher Website | Screenshot Get alerted to all of our Software updates on Twitter at @NeowinSoftware
    • If they don't subtitle it "the search for more money" I'll be a little miffed.  I mean, that was a play on "the search for Spock" which no one freaking knows anymore, but still, they literally named the sequel in the first movie, so ...   (regardless, with everyone still alive on board, I'm super happy)
    • It never was. I hear that year after year. It never becomes that.
    • I use it every day also and have never had an issue with any part of it not working OOTB. Maybe not year of the Linux, but I'm willing to bet there will be a fair amount of people making the switch in the next few months. I know I've helped switch a couple dozen people myself.
  • Recent Achievements

    • First Post
      NeoToad777 earned a badge
      First Post
    • Week One Done
      JoeV earned a badge
      Week One Done
    • One Month Later
      VAT Services in UAE earned a badge
      One Month Later
    • First Post
      LsDmT earned a badge
      First Post
    • Week One Done
      evershinefacilityservice earned a badge
      Week One Done
  • Popular Contributors

    1. 1
      +primortal
      573
    2. 2
      ATLien_0
      246
    3. 3
      +Edouard
      162
    4. 4
      +FloatingFatMan
      144
    5. 5
      Michael Scrip
      113
  • Tell a friend

    Love Neowin? Tell a friend!