Muhammad Shahid
Muhammad Shahid

Reputation: 81

Dictionary: Property or indexer cannot be assigned to: it is read only

I am trying to change the value of Keys in my dictionary as follows:

//This part loads the data in the iterator
List<Recommendations> iterator = LoadBooks().ToList();
//This part adds the data to a list 
List<Recommendations> list = new List<Recommendations>();

        foreach (var item in iterator.Take(100))
        {
            list.Add(item);
        }
        //This part adds Key and List as key pair value to the Dictionary
        if (!SuggestedDictionary.ContainsKey(bkName))
        {
            SuggestedDictionary.Add(bkName, list);

        }
       //This part loops over the dictionary contents 
  for (int i = 0; i < 10; i++)
        {
            foreach (var entry in SuggestedDictionary)
            {
                rec.Add(new Recommendations() { bookName = entry.Key, Rate = CalculateScore(bkName, entry.Key) });
                entry.Key = entry.Value[i];
            }

        }

But it says "Property or Indexer KeyValuePair>.Key Cannot be assigned to. Is read only. What I exactly want to do is change the value of dictionary Key here and assign it another value.

Upvotes: 7

Views: 9232

Answers (1)

TheGeneral
TheGeneral

Reputation: 81593

The only way to do this will be to remove and re-add the dictionary item.

Why? It's because a dictionary works on a process called chaining and buckets (it's similar to a hash table with different collision resolution strategy).

enter image description here

When an item is added to a dictionary, it is added to the bucket that its key hashes to and, if there's already an instance there, it's prepended to a chained list. If you were to change the key, it will need to to go through the process of working out where it belongs. So the easiest and most sane solution is to just remove and re-add the item.

Solution

var data = SomeFunkyDictionary[key];
SomeFunkyDictionary.Remove(key);
SomeFunkyDictionary.Add(newKey,data);

Or make your self an extension method

public static class Extensions
{
   public static void ReplaceKey<T, U>(this Dictionary<T, U> source, T key, T newKey)
   {
      if(!source.TryGetValue(key, out var value))
         throw new ArgumentException("Key does not exist", nameof(key));
      source.Remove(key);
      source.Add(newKey, value);
   }
}

Usage

SomeFunkyDictionary.ReplaceKey(oldKye,newKey);

Side Note : Adding and removing from a dictionary incurs a penalty; if you don't need fast lookups, it may just be more suitable not use a dictionary at all, or use some other strategy.

Upvotes: 12

Related Questions