C# Dictionary.Add(KeyValue, Structure) updates all existing records with last added structure but with the new KeyValue

62 views Asked by At

The Dictionary.Add method updates all the previous records with the last records values but the Key values are correct for the record. Tried creating a test bed for the Dictionary collection with a simple set of code. Add still updates all the previous values. here is the code Trying to load a Dictionary Collection. The app cycles through a file, manipulates a record, records them in the TaxParcel structure and then adds the TaxParcel to the Dictionary ParcelData using the ParcelID as the Key of the Key/Value record and the Add method of the Dictionary. The first record added is correct when examined, the Key value is "1". When a second record is added and examined, the Key value of the second record is "2" and the values associated are correct. But when the first record is examined, the Key value is correct, "1" but the values associated are those of the second (last) added record. Adding a third record updates all the previous values to the values of those last entered but does not change the Key values. Below is the functional code that produced this effect.

    namespace DictionaryCollection_test_bed    
    {

    

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace DictionaryCollection_test_bed
    {
        class Program
        {
            static void Main(string[] args)
            {
                //Set up Dictionary Clooection and instantiate TaxParcel class
                Dictionary<string, TaxParcel> ParcelData = new Dictionary<string, TaxParcel>();
                TaxParcel ParcelPair = new TaxParcel();

                ParcelPair.ParcelID = "1";
                ParcelPair.Owner = "Owner1";
               ParcelPair.Address = "Address1";
               ParcelData.Add(ParcelPair.ParcelID, ParcelPair);
            //this record is correct at this point
            //Key ="1", ParcelID = "1", Owner = "Owner1", Address = "Address1"

                ParcelPair.ParcelID = "2";
                ParcelPair.Owner = "Owner2";
                ParcelPair.Address = "Address2";
               ParcelData.Add(ParcelPair.ParcelID, ParcelPair);
            //Record 1 now has parcel2 values but still with key 1
            //Key ="1", ParcelID = "2", Owner = "Owner2", Address = "Address2"
            //Record 2 has the correct values for the record
            //Key ="2", ParcelID = "2", Owner = "Owner2", Address = "Address2"

            }
        }
        //Class declaration
         public class TaxParcel
         {
             public string ParcelID { get; set; }
             public string Owner { get; set; }
             public string Address { get; set; }
         }

    }

2

There are 2 answers

3
vgwizardx On

You're trying to use a Dictionary to store multiple instances of the TaxParcel class, each identified by a unique ParcelID. But you're reusing the ParcelPair object to add new entries to the ParcelData dictionary.

When you modify ParcelPair's properties after adding it to the dictionary, you're just modifying the same instance stored in it. C# classes are reference types, so ParcelPair refers to an object in memory. So, changing ParcelPair after adding it to the dictionary changes the object the dictionary references.

To correctly add multiple unique TaxParcel instances to the dictionary, you need to instantiate a new TaxParcel object for each parcel you want to add like this:

namespace DictionaryCollection_test_bed
{



    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace DictionaryCollection_test_bed
    {
        class Program
        {
            static void Main(string[] args)
            {
                //Set up Dictionary collection and instantiate TaxParcel class
                Dictionary<string, TaxParcel> ParcelData = new
                    Dictionary<string, TaxParcel>();
                TaxParcel ParcelPair = new TaxParcel();

                ParcelPair.ParcelID = "1";
                ParcelPair.Owner = "Owner1";
                ParcelPair.Address = "Address1";
                ParcelData.Add(ParcelPair.ParcelID, ParcelPair);
                //this record is correct at this point
                //Key ="1", ParcelID = "1", Owner = "Owner1", Address = "Address1"

                TaxParcel ParcelPair2 = new TaxParcel();// <Add this and rename ParcelPair to ParcelPair2
                ParcelPair2.ParcelID = "2";
                ParcelPair2.Owner = "Owner2";
                ParcelPair2.Address = "Address2";
                ParcelData.Add(ParcelPair2.ParcelID, ParcelPair2);
                //Key ="2", ParcelID = "2", Owner = "Owner2", Address = "Address2"
                // Now they should have the correct values
            }
        }

        //Class declaration
        public class TaxParcel
        {
            public string ParcelID { get; set; }
            public string Owner { get; set; }
            public string Address { get; set; }
        }

    }
}
3
mtmk On

You need to create a new instance every time:

var dictionary = new Dictionary<int, MyData>();

var one = new MyData { Name = "One" };
dictionary.Add(1, one);

var two = new MyData { Name = "Two" };
dictionary.Add(2, two);

class MyData
{
    public string Name { get; set; }
}

Because dictionary keeps a reference to you class instance, any changes to the original object would be available when you access the same object using the dictionary:

one.Name = "uno";

Console.WriteLine(dictionary[1].Name); // Output: uno