Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#词典问题_C#_Dictionary - Fatal编程技术网

C#词典问题

C#词典问题,c#,dictionary,C#,Dictionary,我编写了以下代码结构: public Dictionary<string, Dictionary<string, Object>> file_data = new Dictionary<string, Dictionary<string, Object>>(); public Form1() { InitializeComponent(); Dictionary<string, Object> temporary =

我编写了以下代码结构:

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());
}
public Dictionary file_data=new Dictionary();
公共表格1()
{
初始化组件();
字典临时=新字典();
临时。添加(“内容”,空);
临时。添加(“水滴列表”,假);
临时添加(“有效的_文件”,false);
文件\u data.Add(“基本\u数据”,临时);
文件\u数据。添加(“供应商\u数据\u 1”,临时);
文件数据[“基本数据”][“水滴列表”]=true;
MessageBox.Show(文件_数据[“供应商_数据_1”][“droplist”].ToString());
}

我只是想更新
[“基本数据”][“数据点列表”]
,但代码也更新了
[“供应商数据1”][“数据点列表”]
值(messagebox显示true)。它为什么这样做?我如何调整代码,使
文件\u数据[“基本数据”][“水滴列表”]
只会更改?
字典
必须保持其结构。

对象
是引用类型。有一个很好的解释

值类型的变量包含该类型的值。例如,int类型的变量可能包含值42。这与引用类型的变量不同,引用类型包含对该类型实例(也称为对象)的引用。将新值指定给值类型的变量时,将复制该值。将新值指定给引用类型的变量时,复制的是引用,而不是对象本身

你应该克隆那本字典。就像解释的那样。你可以这样做:

file_data.Add(“供应商_数据_1”,克隆词典(临时));
或者更好的是,在第一本词典的基础上创建一本新词典

文件_数据。添加(“供应商_数据_1”,新字典(临时));

添加同一对象两次:

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));
正如@hardkoded所说的,这是一个好消息

//在这里定义'temporal'对象
字典临时=新字典();
//在这里,您添加了一个指向“temporal”对象的引用/指针,作为这些键的值
文件\u data.Add(“基本\u数据”,临时);
文件\u数据。添加(“供应商\u数据\u 1”,临时);
//当您获得“基本数据”和“供应商数据”键的值时,您将获得对“临时”对象的引用。
var baseData=文件数据[“基本数据”];
var supplierData1=文件数据[“供应商数据”1];
//如果比较这些变量,就会发现它们是对同一对象的引用!
if(baseData==supplierData1)//true
WriteLine(“它们是一样的!”);

因此,对
file\u data[“base\u data”]
所做的任何更改都将应用于
file\u data[“supplier\u data\u 1”]
,因为它们当前是指向同一对象的引用/指针

基本数据和供应商数据指向同一个字典。您可以通过执行
file_data.Add(“供应商_data_1”,新字典(临时)),使供应商_data_1指向字典的单独副本
我想知道,是什么让你相信在第一本字典的基础上创建一本新字典比克隆它更好?你必须克隆
字典中的所有
对象
,或者对该字典中任何引用类型的更改都会在这两本字典中更改。基本上,因为您使用的是内置的.NET代码,而不是编写自己的克隆代码。@MikaelDúiBolinder确实如此。但他在那里只使用值类型。但这一点很好。在这种情况下,您需要一个深度克隆算法。然后可能使用
使用ValueTypeDictionary=Dictionary
// 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!");