你如何在.NET中克隆字典?

uri*_*ium 38 .net data-structures

我知道我们应该使用字典而不是哈希表.我找不到克隆字典的方法.即使将它转换为ICollection,我也是为了获得SyncRoot,我知道这也是不赞成的.

我现在忙着改变它.我是否正确地假设无法以通用方式实现任何类型的克隆,这就是字典不支持克隆的原因?

Fil*_*erg 57

使用带有Dictionary的构造函数.看这个例子

var dict = new Dictionary<string, string>();

dict.Add("SO", "StackOverflow");

var secondDict = new Dictionary<string, string>(dict);

dict = null;

Console.WriteLine(secondDict["SO"]);
Run Code Online (Sandbox Code Playgroud)

只是为了好玩..你可以使用LINQ!这是一种更通用的方法.

var secondDict = (from x in dict
                  select x).ToDictionary(x => x.Key, x => x.Value);
Run Code Online (Sandbox Code Playgroud)

编辑

这应该适用于参考类型,我尝试了以下内容:

internal class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public User Parent { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

以及上面的修改代码

var dict = new Dictionary<string, User>();

dict.Add("First", new User 
    { Id = 1, Name = "Filip Ekberg", Parent = null });

dict.Add("Second", new User 
    { Id = 2, Name = "Test test", Parent = dict["First"] });

var secondDict = (from x in dict
                  select x).ToDictionary(x => x.Key, x => x.Value);

dict.Clear();

dict = null;

Console.WriteLine(secondDict["First"].Name);
Run Code Online (Sandbox Code Playgroud)

其中输出"Filip Ekberg".

  • 请记住,第一种方法将创建浅拷贝,即对象也不会被复制.对于不是真正问题的字符串,但对于其他引用类型,它可能是. (9认同)
  • 值得注意的是:这种方法不会克隆源`IDictionary`的`IEqualityComparer`,即如果你有一个带有`StringComparer.OrdinalIgnoreCase`的`IDictionary`. (3认同)
  • 您的参考示例具有误导性/不正确性 - 引用的类型在两个集合中仍然是相同的实例:https://dotnetfiddle.net/AMRtta - 更改`dict ["First"].Name`并且它也将被更改在`secondDict ["First"].姓名`.从一个集合中删除它与修改它不是一回事.另外,如果你要使用Linq:只是`dict.ToDictionary`而不是`(来自d中的x选择x).ToDictionary`. (2认同)