背景 我有一个字典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();
}
答案 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);
}