我编写了以下代码结构:
public Dictionary<string, Dictionary<string, Object>> file_data = new Dictionary<string, Dictionary<string, Object>>();
public Form1()
{
InitializeComponent();
Dictionary<string, Object> temporary = new Dictionary<string, Object>();
temporary.Add("content", null);
temporary.Add("droplist", false);
temporary.Add("valid_file", false);
file_data.Add("base_data", temporary);
file_data.Add("supplier_data_1", temporary);
file_data["base_data"]["droplist"] = true;
MessageBox.Show(file_data["supplier_data_1"]["droplist"].ToString());
}
我只想更新["base_data"]["droplist"]
,但是代码也更新了["supplier_data_1"]["droplist"]
的值(消息框显示为true)。为什么这样做呢?我该如何适应仅更改file_data["base_data"]["droplist"]
的代码? Dictionary
必须保持其结构。
答案 0 :(得分:4)
Object
是引用类型。 Microsoft Value Types post有一个很好的解释
值类型的变量包含该类型的值。例如,int类型的变量可能包含值42。这不同于引用类型的变量,后者包含对该类型的实例(也称为对象)的引用。将新值分配给值类型的变量时,将复制该值。当您为引用类型的变量分配新值时,将复制引用,而不是对象本身。
您应该克隆该词典。就像它解释的here一样。您可以执行以下操作:
file_data.Add("supplier_data_1", CloneDictionary(temporary));
或更妙的是,根据第一个字典创建一个新字典。
file_data.Add("supplier_data_1", new Dictionary<string, object>(temporary));
答案 1 :(得分:0)
您要两次添加同一对象:
file_data.Add("base_data", temporary);
file_data.Add("supplier_data_1", temporary);
temporary
变量指向内存中的对象。现在,字典中的两个引用也指向内存中的该对象。但是内存中仍然只有一个对象。通过对该对象的任何引用,都可以看到对该对象所做的任何更新。
为了在字典中具有两个不同的对象,您需要创建第二个对象。您可以通过在代码中创建两个变量,填充每个变量,并将其添加到结果字典中来手动执行操作。或者,如果它们都是简单的值类型,您也可以围绕相同的值创建一个新字典:
file_data.Add("supplier_data_1", temporary.ToDictionary(x => x.Key, x => x.Value));
答案 2 :(得分:0)
正如@hardkoded所说的,它是a reference type。
// Here you define `temporal` object
Dictionary<string, Object> temporary = new Dictionary<string, Object>();
// Here you add a reference/pointer to the `temporal` object as values to these keys
file_data.Add("base_data", temporary);
file_data.Add("supplier_data_1", temporary);
// When you get the values for the "base_data" and "supplier_data_1" keys, you get a refence to the `temporal`object.
var baseData = file_data["base_data"];
var supplierData1 = file_data["supplier_data_1"];
// If you compare those variables, you'll find out that they are references to the same object!
if (baseData == supplierData1) // true
Debug.WriteLine("They are the same!");
因此,对file_data["base_data"]
所做的任何更改都将应用于file_data["supplier_data_1"]
,因为它们当前是同一对象的引用/指针!