2

So I have written a program in which I need to do a deep copy of several objects. In my case I cannot use serialization which would've solved this problem with ease. Is there another way to solve this problem without manually copying all the attributes in the classes?

user1106784
  • 153
  • 1
  • 3
  • 10
  • 1
    Nope. You can use reflection and recursion to create a general purpose deep copy method. – ChrisF Feb 16 '12 at 22:33
  • 2
    http://stackoverflow.com/questions/129389/how-do-you-do-a-deep-copy-an-object-in-net-c-specifically edit: Why can't serialization be used? – mowwwalker Feb 16 '12 at 22:33
  • 4
    Or you can make your objects immutable, thus rendering a deep copy unnecessary. – Adam Mihalcin Feb 16 '12 at 22:33
  • 1
    I think this question is a duplicate of [link](http://stackoverflow.com/questions/78536/cloning-objects-in-c-sharp) @Walkerneo 's link uses serialization. – Steven Schroeder Feb 16 '12 at 22:34
  • 1
    If you can't serialize your object graph you most likely can't properly deep clone it either. What is your reason why you can't serialize? – Alexei Levenkov Feb 16 '12 at 22:44
  • I am using this in a game in XNA and the classes I want to clone are gamecomponents which need game to function, and game cannot be serialized. – user1106784 Feb 16 '12 at 23:04
  • 1
    "and game cannot be serialized" is exactly the reason why one can't make generic deep copy that handles all types - there are types that can't be cloned (more obvious type is Console object), so for every case you need to have special code that clones some and reuses other objects making not honest deep copy... – Alexei Levenkov Feb 16 '12 at 23:47

1 Answers1

2

You could do this using reflection. Code project has an example: http://www.codeproject.com/Articles/38270/Deep-copy-of-objects-in-C

UPDATE 1
There are also examples on StackOverflow using BinaryFormatter, as noted in the comments to your question:

How do you do a deep copy of an object in .NET (C# specifically)?
Deep cloning objects

If you want another approach, then if possible you can make all of your classes implement ICloneable, make use of MemberwiseClone, and use recursion to do the deep copy. Personally, I'd start with BinaryFormatter.

UPDATE 2
If GameComponent is not serializable (which judging from the documentation it does not appear to be), then you could use this pattern to help create copies of your classes that derive from GameComponent. Wrap all of the data you need to copy in its own class and mark that class as serializable, and then implement ICloneable on your GameComponent class. For example:

public class MyGameComponent : GameComponent, ICloneable
{
    public MyGameComponent(Game game) : base(game) { }
    public MyGameComponentData MyGameComponentData { get; set; }

    public object Clone()
    {
        var clone = (MyGameComponent)MemberwiseClone();

        var formatter = new BinaryFormatter();
        using (var stream = new MemoryStream())
        {
            formatter.Serialize(stream, this.MyGameComponentData);
            stream.Seek(0, SeekOrigin.Begin);
            clone.MyGameComponentData = 
                        (MyGameComponentData)formatter.Deserialize(stream);
        }

        return clone;
    }
}

[Serializable]
public class MyGameComponentData
{
    public string Data1 { get; set; }
    public List<string> Data2 { get; set; }
}
Community
  • 1
  • 1
rsbarro
  • 27,021
  • 9
  • 71
  • 75
  • Sorry, but I'm not familiar with XNA, are the game components classes that you created or part of a library that you cannot change? I'm guessing you can't change them and they are not marked as `[Serializable]`, is that correct? – rsbarro Feb 16 '12 at 23:07
  • Yeah they are in the framework and cannot be marked with [Serializable]. I read a bit about MemberwiseClone but tought it would still return the same ref as in a shallow copy, but if there is some sort of way to make it do a deep copy I will check into. Thanks for the links I will keep reading – user1106784 Feb 16 '12 at 23:11
  • Just curious, what are the class names? – rsbarro Feb 16 '12 at 23:12
  • I create the classes myself but I inherit from GameComponent class – user1106784 Feb 16 '12 at 23:17
  • @user1106784 Please check the update to my answer, will that approach work for you? – rsbarro Feb 17 '12 at 11:52