我如何在C#中克隆字典 [英] how do i clone a dictionary in C#

查看:550
本文介绍了我如何在C#中克隆字典的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何克隆字典?

如果我更改源字典,新字典不应该更改。

有什么想法吗?

How do I clone a dictionary?
If I change a source dictionary, the new dictionary should not get changed.
Any idea?

推荐答案

你需要实现ICloneable。

将你的字典定义为一个类,派生自Dictionary:

You need to implement ICloneable.
Define your dictionary as a class, derived from Dictionary:
public class CloneableDictionary<TKey, TValue> : Dictionary<TKey, TValue> where TValue : ICloneable
    {
    public CloneableDictionary<TKey, TValue> Clone()
        {
        CloneableDictionary<TKey, TValue> clone = new CloneableDictionary<TKey, TValue>();
        foreach (KeyValuePair<TKey, TValue> kvp in this)
            {
            clone.Add(kvp.Key, (TValue) kvp.Value.Clone());
            }
        return clone;
        }
    }

然后你可以使用克隆方法:

Then you can use the Clone method:

CloneableDictionary<int, string> dic = new CloneableDictionary<int, string>() {
    {1, "Key1"},
    {2, "Key2"}};
CloneableDictionary<int, string> dicCopy = dic.Clone();
dicCopy[1] = "Key Changed";
foreach (KeyValuePair<int, string> kvp in dic)
    {
    Console.WriteLine(kvp.Key.ToString() + ":" + kvp.Value);
    }
foreach (KeyValuePair<int, string> kvp in dicCopy)
    {
    Console.WriteLine(kvp.Key.ToString() + ":" + kvp.Value);
    }


使用LINQ会是这样的:



Using LINQ it would be something like:

var originalDictionary = ...;
var clonedDictionary = originalDictionary.ToDictionary(
    x => x.Key, // Typically no cloning necessary (immuable)
    x => (TargetType)x.Value.Clone()  // Do the copy how you want
);





如果现有的字典值各有一个,这可能是首选的方法他们的复制方式......



This could be the prefered method to uses if your existing dictionary values each have their way to be copied...


我明白了:你的第二行解释了世界克隆的含义。



这是深度克隆的问题。深度克隆在某种程度上总是一种自定义的东西。



您可以简单地创建一个新的字典,按所有键值对循环,然后添加每个字典元素到你的新词典。如果您的键和值类型都是值类型或字符串类型,它将完美地工作。在所有其他情况下,您需要在新字典中插入旧字典中的键和值,而不是其克隆。问题是克隆密钥和价值有多深?



如果你只需要为这对类型做一次,这不是问题。如何使它成为通用的?

...当我准备我的代码时,我发现Griff已经正确回答了。请使用他的答案。



我唯一需要注意的是:此代码的自定义减少为 IClonable 在您的值类型中。您需要提供所需的克隆级别,因为如果您拥有包含包含其他引用类型的引用类型的值类型,并且您需要更改最深类型的值,则您的浅层克隆可能不够深。



严格来说,您可能还需要克隆密钥(并在通用约束中应用 IClonable )但实际上这应该是多余的因为字典中键的功能意味着它们应该是不可变的。



-SA
I understand: your second line explains the meaning of the world "clone".

This is a problem of deep cloning. The deep cloning is always a custom stuff, to some extend.

You can simply create a new dictionary, take a loop by all key-value pairs and than add each element to your new dictionary. It will perfectly work if your key and value types are all of the value type or string type. In all other cases you need to insert in new dictionary not the keys and values from your old dictionary, but their clones. The problem is how deep is the cloning of the key and value?

If you need to do it once just for the pair of types, this is not a problem. How to make it generic?
…when I was preparing my code I found that Griff already answered correctly. Please use his answer.

My only extra note is this: the customization of this code is reduced to implementation of IClonable in your value type. You need to provide required level of cloning, because if your have, say, a value type containing reference type containing another reference type, and you need to change the most deep type's value, your shallow cloning maybe not deep enough.

Strictly speaking, you may need to clone keys as well (and apply IClonable in generic constraint) but in practice this should redundant because the functionality of the keys in the dictionary imply they should be immutable.

—SA


这篇关于我如何在C#中克隆字典的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆