1

Background: I have a dictionary diskInfo with key as string and value as dictionary of type string, double. For each entry into the foreach loop, I calculate the disk space and store the result into spaceInfo dictionary. This is then passed on to be stored as the value for corresponding key in diskInfo dictionary.

Problem Each time I clear existing entries in spaceInfo and readd the key value pairs before storing into diskInfo dictionary. At the end of the loop, diskInfo dictionary has keys stored in correctly, but count of values is 0 for all keys. I am new to using Dictionaries, so could you please help in explaining why this happens.

Thankyou

Dictionary<string, double> spaceInfo = new Dictionary<string, double>();
Dictionary<string, Dictionary<string, double>> diskInfo = new Dictionary<string, Dictionary<string, double>>();
foreach (ManagementObject mo in queryCollection)
        {
            double size = Convert.ToDouble(mo["Size"]) / divisor;
            double free = Convert.ToDouble(mo["FreeSpace"]) / divisor;

            double percentFree = (free / size) * 100;

            spaceInfo.Add("size",size);
            spaceInfo.Add("freeSpace",free);
            spaceInfo.Add("percentFree",percentFree);

            diskInfo.Add(Convert.ToString(mo["Name"]),spaceInfo);

            spaceInfo.Clear();
        }
user132689
  • 11
  • 1
  • 3

2 Answers2

0

Try Something like this

diskInfo.Add(Convert.ToString(mo["Name"]), new Dictionary<string, double>(spaceInfo));

The problem because of shallow copying. You must perform deep copying to avoid such problems. The copy constructor in the Dictionary class might help you solving the problem since it creates new instance from the spaceInfo object.

But the better way to do this is by creating class for the SpaceInformation.

class SpaceInfo
{
    private double _size;
    private double _free;
    private double _percentFree;

    public double Size
    {
        get;
        set;
    }

    public double Free 
    {
        get;
        set;
    }

    public double PercentFree
    {
        get;
        set ;
    }

    public SpaceInfo(double size, double free)  
    {
        Size = size;
        Free = free;
        PercentFree = (free / size) * 100;
    }
}

 /*Inside the loop*/
 double size = Convert.ToDouble(mo["Size"]) / divisor;
 double free = Convert.ToDouble(mo["FreeSpace"]) / divisor;
 SpaceInfo spaceInfo = new SpaceInfo(size, free);
 Dictionary<string, SpaceInfo> diskInfo = new Dictionary<string, SpaceInfo>();
 diskInfo.Add(Convert.ToString(mo["Name"]), spaceInfo);



`
sujith karivelil
  • 28,671
  • 6
  • 55
  • 88
Praburaj
  • 613
  • 8
  • 21
0

Hope that you missed the point that, Dictionary is a reference type variable so if you made any changes in an instance means it will reflect all the places, so have to create separate instance in each iteration, You should try something like this:

foreach (ManagementObject mo in queryCollection)
{
   double size = Convert.ToDouble(mo["Size"]) / divisor;
   double free = Convert.ToDouble(mo["FreeSpace"]) / divisor;
   double percentFree = (free / size) * 100;

   // Adding items here

   diskInfo.Add(mo["Name"].ToString(), new Dictionary<string, double>()
                                       {
                                           {"size",size},
                                           {"freeSpace",free},
                                           {"percentFree",percentFree}    
                                       } 

}

Or even like this by few modifications to your code; which means you have to create a new instance of spaceInfo in each iteration instead of clearing them.

foreach (ManagementObject mo in queryCollection)
{
    double size = Convert.ToDouble(mo["Size"]) / divisor;
    double free = Convert.ToDouble(mo["FreeSpace"]) / divisor;
    double percentFree = (free / size) * 100;

    spaceInfo = new Dictionary<string, double>();
    spaceInfo.Add("size",size);
    spaceInfo.Add("freeSpace",free);
    spaceInfo.Add("percentFree",percentFree);

    diskInfo.Add(Convert.ToString(mo["Name"]),spaceInfo);
}
sujith karivelil
  • 28,671
  • 6
  • 55
  • 88