0

What is the simplest way to create a deep copy of an OrderedDictionary? I tried making a new variable like this:

var copy = dict[x] as OrderedDictionary;

But if I update the values/keys in copy, the dictionary in dict[x] gets updated as well.

Edit: dict is another OrderedDictionary.

Kevin M.
  • 139
  • 2
  • 12

3 Answers3

2

You should be able to use a generic deep cloning method. An example of deep cloning from msdn magazine:

Object DeepClone(Object original)
{
    // Construct a temporary memory stream
    MemoryStream stream = new MemoryStream();

    // Construct a serialization formatter that does all the hard work
    BinaryFormatter formatter = new BinaryFormatter();

    // This line is explained in the "Streaming Contexts" section
    formatter.Context = new StreamingContext(StreamingContextStates.Clone);

    // Serialize the object graph into the memory stream
    formatter.Serialize(stream, original);

    // Seek back to the start of the memory stream before deserializing
    stream.Position = 0;

    // Deserialize the graph into a new set of objects
    // and return the root of the graph (deep copy) to the caller
    return (formatter.Deserialize(stream));
}
tdc
  • 8,219
  • 11
  • 41
  • 63
  • 1
    All type should be `serializable`(even ecapsulated types etc) in order to work – Sriram Sakthivel Sep 18 '13 at 13:35
  • Also, if any key (or value) in the dictionary contains any events, binary serialization will try and serialize the event along with the entire listener, which can be troublesome. It isn't very fast either. See http://stackoverflow.com/a/11308879/168719 as an alternative – Konrad Morawski Sep 18 '13 at 13:49
0

What type of objects are you storing in your dictionary ?

You'll need to iterate over the content of the Dictionary and clone/duplicate the contents in some way.

If your object implements ICloneable you could do something like,

Dictionary<int, MyObject> original = new Dictionary<int, MyObject>();
... code to populate original ...

Dictionary<int, MyObject> deepCopy = new Dictionary<int, MyObject>();

foreach(var v in a)
{
    MyObject clone = v.Value.Clone();
    b.Add(v.Key, clone);
}
Eoin Campbell
  • 43,500
  • 17
  • 101
  • 157
  • I'm storing all sorts of different objects, from DataTables to Strings to Decimals to Integers... – Kevin M. Sep 18 '13 at 13:16
  • `ICloneable` is for shallow copy – Sriram Sakthivel Sep 18 '13 at 13:31
  • 2
    @SriramSakthivel not necessarily. From http://msdn.microsoft.com/en-us/library/system.icloneable.aspx: *The ICloneable interface simply requires that your implementation of the Clone method return a copy of the current object instance. It does not specify whether the cloning operation performs a deep copy, a shallow copy, or something in between.* – user247702 Sep 18 '13 at 13:38
  • @Stijn My mistake, usually it is implemented as shallow copy. – Sriram Sakthivel Sep 18 '13 at 13:41
0

I can't tell from your question if dict is a dictionary of dictionaries? The simplest way to make a deep copy of a collection is to iterate through its members and clone each one.

If your value implements ICloneable:

OrderedDictionary newDict = new OrderedDictionary();
foreach(DictionaryEntry entry in OriginalDictionary)
{
     newDict[entry.Key] = entry.Value.Clone();
}

If your values can't be Clone()d, you'll have to copy them another way.

OrderedDictionary newDict = new OrderedDictionary();
foreach(DictionaryEntry entry in OriginalDictionary)
{
     MyClass x = new MyClass();
     x.myProp1 = entry.Value.myProp1 as primitive value;
     x.myProp2 = entry.Value.myProp2 as primitive value;
     newDict[entry.Key] = x;
}
HTTP 501
  • 126
  • 15