C#将元素添加到Dictionary,键为字符串,值为另一个词典

时间:2016-12-22 04:55:51

标签: c# dictionary

背景 我有一个字典diskInfo,键为字符串,值为string类型的字典,double。对于foreach循环中的每个条目,我计算磁盘空间并将结果存储到spaceInfo字典中。然后将其传递以存储为diskInfo字典中相应键的值。

问题 每次我清空spaceInfo中的现有条目并在存储到diskInfo字典之前读取键值对。在循环结束时,diskInfo字典正确存储了密钥,但所有密钥的值计数均为0。我是新手使用词典,所以请你帮忙解释一下为什么会这样。

谢谢你

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();
        }

2 个答案:

答案 0 :(得分:0)

尝试类似这样的事情

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

由于浅层复制而导致的问题。 您必须执行深度复制以避免此类问题。 Dictionary类中的复制构造函数可以帮助您解决问题,因为它从spaceInfo对象创建新实例。

但更好的方法是为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);



`

答案 1 :(得分:0)

希望您错过了这样的观点,即Dictionary是一个引用类型变量,因此如果您在实例中进行任何更改意味着它将反映所有位置,那么必须在每次迭代中创建单独的实例, 你应该尝试这样的事情:

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}    
                                       } 

}

或者甚至通过对您的代码进行少量修改来实现这一点;这意味着您必须在每次迭代中创建spaceInfo的新实例,而不是清除它们。

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);
}