繁体   English   中英

如何创建字典副本 <int,List<int> &gt;而不影响原始(C#)?

[英]How do I create a copy of a Dictionary<int,List<int>> without affecting the original (C#)?

我在C#中使用字典,花了几个小时弄清楚为什么我的程序不起作用,原因是当我操纵我制作的字典副本时,这些操纵也会影响原始的字典由于某种原因。

我将问题归结为以下示例:

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);
    }
}

在此代码中,当我将一个元素添加到副本中与键1对应的列表中时,该元素也会出现在原始字典中。

当我在线搜索时,它似乎与“引用类型”有关,建议的修复程序似乎总是包含类似于以下内容的代码

Dictionary<int, List<int>> Dcopy = new Dictionary<int, List<int>>(D);

我确实将其包含在程序中,但是由于某些原因,这不起作用。

关于为什么它在我的情况下不起作用的任何建议,以及有关如何处理的任何建议?

最好的祝福。

您正在执行浅表副本,而不是深表副本。 基本上,您需要遍历字典并创建新列表

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 ,这是一种值类型,因此您无需“克隆”比列表更深的内容。 如果列表中包含引用类型,那么您还必须另外克隆它们,并可能一直克隆所有引用属性。

字典副本构造函数对字典进行浅表复制。 由于值是列表(引用类型),因此不会克隆列表。 如果要进行拷贝,则还需要克隆值:

    Dictionary<int, List<int>> Dcopy = D.ToDictionary(kvp => kpv.Key,
                                                      kvp => kvp.Value.ToList());

由于值是值类型的集合,因此不需要关闭列表的内容-克隆列表本身就足够了。 密钥相同-它们是值类型,因此无需克隆。

如果不需要列表的深层副本,为什么不简单使用.NET提供的构造函数,避免扩展调用呢?

Dictionary<int, List<int>> Dcopy = new Dictionary<int,List<int>>(D);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM