• 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

    • Just give a great simple monitor. No AI nonsense. What's next? AI mouse that knows where you want to move?
    • Certificates for one of Windows 11's hardware requirements expire soon, here is what to know by Taras Buria Secure Boot is a known term for Windows 11 users. It is one of Windows 11's hardware requirements, and without it, the operating system cannot be installed, at least officially. Secure Boot was introduced in 2012 with the release of Windows 8, and its certificates, first issued in 2011, are set to expire soon. Now, Microsoft has posted a blog post about the importance of this event and why organizations and users must ensure their Secure Boot certificates are up to date. In a nutshell, Secure Boot is a special mechanism that ensures that your PC is using verified firmware and a trusted bootloader. Certificates released in 2011 will expire in June 2026, and if left outdated, will disrupt the integrity of the device startup process. Without new certificates, Windows Boot Manager and Secure Boot components can't receive security fixes, leaving affected devices exposed to bootkit malware (such as BlackLotus), which is very hard to detect with standard antivirus software. Other results of having expired Secure Boot certificates include the inability to trust software signed with new certificates. PCs that could be affected by expired certificates include physical and virtual machines (VMs) with supported versions of Windows 10, Windows 11, Windows Server 2025, Windows Server 2022, Windows Server 2019, Windows Server 2016, Windows Server 2012, Windows Server 2012 R2. Copilot+ PCs released in 2025 are not affected. To avoid these potentially disastrous consequences, Microsoft urges organizations and users to update their entire PC fleet to newer certificates, which were released in 2023: Expiration Date Expiration Certificate Updated Certificate What it does Storing Location June 2026 Microsoft Corporation KEK CA 2011 Microsoft Corporation KEK 2K CA 2023 Signs updates to DB and DBX Key Enrollment Key (KEK) Microsoft Corporation UEFI CA 2011 (or third-party UEFI CA)* Microsoft Corporation UEFI CA 2023 Microsoft Option ROM UEFI CA 2023 Signs third-party OS and hardware driver components Signs third-party option ROMs Allowed Signature database (DB) October 2026 Microsoft Windows Production PCA 2011 Windows UEFI CA 2023 Signs the Windows bootloader and boot components So, what do you need to do? Microsoft says that the easiest solution is to let Microsoft manage your Windows updates. In the upcoming months, Microsoft will release new certificates as part of monthly cumulative updates, so it will take care of everything for you. The company also recommends enrolling Windows 10 devices in the Extended Security Updates program, which is free for regular consumers and paid for enterprises. Microsoft will also provide the necessary certificates for Linux systems that dual-boot Windows. Of course, not every Windows PC can receive such updates. For example, so-called "air-gapped" devices, which are physically isolated from the internet and local networks, cannot receive updates like your home PC does. For such devices, Microsoft offers limited support, which is detailed in the blog post. You can also track Windows Secure Boot certificate updates on a newly published support document. You can check if your system has Secure Boot enabled by pressing Win + R, typing msinfo32, and checking "Secure Boot State."
  • Recent Achievements

    • One Month Later
      jfam earned a badge
      One Month Later
    • First Post
      TheRingmaster earned a badge
      First Post
    • Conversation Starter
      Kavin25 earned a badge
      Conversation Starter
    • One Month Later
      Leonard grant earned a badge
      One Month Later
    • Week One Done
      pcdoctorsnet earned a badge
      Week One Done
  • Popular Contributors

    1. 1
      +primortal
      547
    2. 2
      ATLien_0
      201
    3. 3
      +FloatingFatMan
      176
    4. 4
      Michael Scrip
      147
    5. 5
      snowy owl
      114
  • Tell a friend

    Love Neowin? Tell a friend!