Search code examples
c#dictionaryupdatescontainskeytrygetvalue

How to Avoid Updating item searched by Dictionary?


In .NET WinForms C# app, I have a Dictionary<string, RefItemDetails> collection named listItems. I store data in it on start of the app. In a static class I have as follows:

    // listItems is populated bt reading a file. 
    // No other operations are performed on it, except finding an item.
    public static Dictionary<string, RefItemDetails> itemsList;
    
   // Find RefItemDetails of barcode
    public static RefItemDetails FindRefItem(string barcode)
    {
        RefItemDetails itemDet = null;
        try
        {
            //if (itemsList.TryGetValue(barcode, out itemDet) == false)
            //    System.Diagnostics.Debug.WriteLine("Barcode " + barcode + " not found in Items");
            
            //itemDet = itemsList.First(item => item.Key == barcode);//.First(item => item.Barcode == barcode);

            if (itemsList.ContainsKey(barcode)) 
                itemDet = itemsList[barcode];
        }
        catch (Exception)
        {
            itemDet = null;
        }

        return itemDet;
    }

For retrieving an item from listItems in another class, I use :

    refScannedItem = null;
    // Get Unit Barcode & Search RefItem of it
    refScannedItem = UtilityLibrary.FindRefItem(boxItem.UnitBarcode.Trim());

     // Display BOX item details 
     refScannedItem.Barcode = boxItem.BoxBarcode.Trim();
     refScannedItem.Description = "BOX of " + boxItem.Quantity + " " + refScannedItem.Description;
     refScannedItem.Retail *= boxItem.Quantity;
     refScannedItem.CurrentCost *= boxItem.Quantity;

Here what happens above is, I search for an item & I get it "refScannedItem" and I append the Description of it by "BOX of " + boxItem.Quantity + " " + refScannedItem.Description; . So if the original Description was "Aquafina", I make it "BOXof 10 Aquafina". The nest time I scan the same product, I find the product, but now its descrption has become "Box of 10 Aquafina", so my line of setting Description turns to "BOX of 10 BOX of 10 Aquafina". The same goes on like "BOX of 10 BOX of 10 BOX of 10 Aquafina" and so on.

As you cna see in my find code, I had initially used TryGetValue, then tried using LINQ, then tried using ContainsKey, but in all of them why does the value of listItem get updated.

I understand that as TryGetValue has out parameter, so the value is passed as a reference, and then it will be chnaged. But in listItems[key] also updates it !!! How can I avoid this to happen ? I had selected Dictionary collection for easy & fast searching, but this part gives a lot of problems and a big bug too on my app. I couldn't find nay solution where the receive the value but shouldn't be updated. All articles shows how to search & update it.

Kindly suggest a solution for the above. Any help is highly appreciated.

Thanks


Solution

  • You return a pointer to the item contained in your Dictionary, so it makes sense that any manipulations you make to this Object will be stored in the original Dictionary object.

    What you want to do is, in FindRefItem, return a pointer to a copy of your RefItemDetails object.

    An easy way to do this would be to write a new constructor. Something like:

    public RefItemDetails(RefItemDetails original)
    {
       this.Barcode = original.Barcode ;
       this.Description = original.Description ;
       this.Retail = original.Retail ;
       this.CurrentCost = original.CurrentCost ;
       //Set any other properties here
    }
    

    and then replace return itemDet; with return new RefItemDetails(itemDet);