字典的C#问题

时间:2019-02-20 12:52:48

标签: c# dictionary

我编写了以下代码结构:

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必须保持其结构。

3 个答案:

答案 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"],因为它们当前是同一对象的引用/指针!