我在C#中使用词典,我花了几个小时搞清楚为什么我的程序不起作用,原因是当我操作我制作的字典副本时,这些操作也是由于某种原因影响原始字典。
我已将问题归结为以下示例:
const React = require('react');
const ReactDOM = require('react-dom');
class Item extends React.Component {
render(){
let item = this.props.store.item;
return (
<div>
<h1><a href={items.url}>{item.title}</a></h1>
<h2>{item.score} - {item.by.id}</h2>
<hr />
</div>
);
}
};
// Create the mount point and attach it to the DOM
const mountNode = document.createElement('div');
document.body.appendChild(mountNode);
const item = {
id: '1337',
url: 'http://google.com',
title: 'Google',
score: 100,
by: {id: 'clay'},
};
ReactDOM.render(
<Item store={{item}} />,
mountNode
);
在此代码中,当我向副本中的键1对应的列表中添加元素时,此元素也会出现在原始字典中。
当我在线搜索时,它似乎与“引用类型”有关,推荐的修复似乎总是涉及类似于
的代码using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
Dictionary<int, List<int>> D = new Dictionary<int, List<int>>();
List<int> L1 = new List<int>(){ 1, 2, 3 };
List<int> L2 = new List<int>() { 4, 5, 6 };
D.Add(1,L1);
D.Add(2,L2);
Dictionary<int, List<int>> Dcopy = new Dictionary<int, List<int>>(D);
Dcopy[1].Add(4);
}
}
我确实包含在我的程序中,但出于某种原因,这不起作用。
关于为什么它在我的情况下不起作用的任何建议,以及关于该做什么的任何建议?
最好的问候。
答案 0 :(得分:6)
您正在进行浅层复制,而不是深层复制。您基本上需要遍历字典并创建新列表
var Dcopy = new Dictionary<int, List<int>>();
foreach (var entry in D)
{
Dcopy.Add(entry.Key, new List<int>(entry.Value));
}
或者您可以使用以下Linq而不是foreach
var DCopy = D.ToDictionary(entry => entry.Key, entry => new List<int>(entry.Value));
由于您的列表包含int
,这是一种值类型,您不需要克隆&#34;比列表更深。相反,如果列表包含引用类型,那么您还必须另外克隆它们,并且可能还有任何引用属性。
答案 1 :(得分:4)
字典复制构造函数生成字典的浅副本。由于值是列表(引用类型),因此不会克隆列表。如果您想制作深副本,您还需要克隆这些值:
Dictionary<int, List<int>> Dcopy = D.ToDictionary(kvp => kpv.Key,
kvp => kvp.Value.ToList());
由于值是值类型的集合,因此无需关闭列表的内容 - 克隆列表本身就足够了。密钥相同 - 它们是值类型,因此不需要克隆。
答案 2 :(得分:-1)
如果您不需要列表的深副本,为什么不简单地使用.NET提供的构造函数,避免扩展调用?
Dictionary<int, List<int>> Dcopy = new Dictionary<int,List<int>>(D);