Click here to Skip to main content
15,891,864 members
Please Sign up or sign in to vote.
4.83/5 (6 votes)
See more:
How do I clone a dictionary?
If I change a source dictionary, the new dictionary should not get changed.
Any idea?
Posted
Updated 7-Mar-11 21:13pm
v2
Comments
Sergey Alexandrovich Kryukov 8-Mar-11 3:13am    
I like Question, my 5.
(However, there are problems. You need to use correct capitalization, punctuation and spelling. For such a case, I'll do a fix, but please remember about it next time -- this is a matter of politeness.)
--SA

You need to implement ICloneable.
Define your dictionary as a class, derived from Dictionary:
C#
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:
C#
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);
    }
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 8-Mar-11 2:51am    
I started to prepare approximately the same code, but you're faster :-)
My 5! (I'll modify my Answer...)
--SA
Sergey Alexandrovich Kryukov 8-Mar-11 3:00am    
OK, I references you Answer in mine instead of writing my code. Consider my Answer as a rationale for your code... :-)
--SA
vivektp 8-Mar-11 3:30am    
can i do this using Linq ?
Philippe Mori 18-Jul-11 22:29pm    
I have added a solution with LINQ.
Mohammad A Rahman 18-Jul-11 22:35pm    
My 5.
I like the solution.
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...
 
Share this answer
 
v2
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
 
Share this answer
 
v2
Comments
Mohammad A Rahman 18-Jul-11 22:35pm    
My 5.
Good explanation.
Sergey Alexandrovich Kryukov 18-Jul-11 23:23pm    
Thank you, Mohammad.
--SA
If the Type of the Value component of your Dictionary is not a reference Type, then you can use the Dictionary constructor that takes an existing Dictionary as an argument to clone it.
C#
public Dictionary<int, string> sourced = new Dictionary<int, string>
{
    {0,"string0"},{1, "string1"}
};

// test in some method
Dictionary<int,> newd = new Dictionary<int,>(sourced);
newd[1] = "hello";

// now examine value in 'sourced: note there is no change
 
Share this answer
 
Comments
Maciej Los 6-Dec-15 15:17pm    
Bill, this is very old question. I've seen many valueable answers which have been down-voted because of it.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900