views:

11836

answers:

7

I want a true deep copy. In Java, this was easy, but how do you do it in C#?

+1  A: 

I'm still on the C# learning curve, but when I looked into this it appeared that you had to roll your own deep copy function if you wanted one.

17 of 26
I cant parse this sentence. Can you explain and I'll remove the comment (not -1ing, just 100% dont get what your point is)
Ruben Bartelink
+51  A: 

I've seen a few different approaches to this, but I use a generic utility method as such:

public static T DeepClone<T>(T obj)
{
 using (var ms = new MemoryStream())
 {
   var formatter = new BinaryFormatter();
   formatter.Serialize(ms, obj);
   ms.Position = 0;

   return (T) formatter.Deserialize(ms);
 }
}

Note that your class MUST be marked as [Serializable] in order for this to work.

Kilhoffer
What happen if the object have event, Do they lost everything because of the serialization?
Daok
Event subscribes are included into serialization graph, since BinaryFormatter uses fields via reflection, and events are just fields of delegate types plus add/remove/invoke methods.You can use [field: NonSerialized] on event to avoid this.
Ilya Ryzhenkov
This only works if all members are marked [Serializable]
Christopher
What is that undeclared "stream" variable? Or is it something just in C# and not VB.NET? I converted everything but that variable.
HardCode
No, that's a typo. I'm correcting it now...
Kilhoffer
ms.Location or ms.Position? or is this something to do with the Framework version?
dr. evil
+1  A: 

this is one way: http://www.thomashapp.com/node/106 another is to use binary serialization.

Mladen
A: 

What does a Deep Copy do? Does it copy the bitstream?

Scott
A deep copy is something that copies EVERY field of an object. A shallow copy will only create a new object and point all the fields to the original.
swilliams
A: 

Have you tried using the struct construct? I'm a newbie to c# myself (also coming from the Java camp) but this may be useful to you.

http://www.c-sharpcorner.com/UploadFile/rajeshvs/StructuresInCS11112005234341PM/StructuresInCS.aspx

I.e.

With structs you can do this (psuedo code):

A = 10;
B = A;
B = 20

print(A) // out's 10
print(B) // out's 20

Kind of like java primatives, but structs can have methods and other variables just as regular classes

Richie_W
All you're doing is reassigning B's value. How does this answer his question?
junkforce
+10  A: 

Kilhoffer's code doesn't compile. Here's the corrected version.

    public static T DeepCopy<T>(T obj)
    {
        object result = null;

        using (var ms = new MemoryStream())
        {
            var formatter = new BinaryFormatter();
            formatter.Serialize(ms, obj);
            ms.Position = 0;

            result = (T)formatter.Deserialize(ms);
            ms.Close();
        }

        return (T)result;
    }
Almost forgot to mention, make sure the class/object you're doing a DeepCopy on is marked as Serializable [Serializable]public class MyClass
I've corrected my code. I had a variable mispelled. It's good now.
Kilhoffer
+15  A: 

Building on Kilhoffer's solution...

With C# 3.0 you can create an extension method as follows:

public static class ExtensionMethods
{
    // Deep clone
    public static T DeepClone<T>(this T a)
    {
        using (MemoryStream stream = new MemoryStream())
        {
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(stream, a);
            stream.Position = 0;
            return (T) formatter.Deserialize(stream);
        }
    }
}

which extends any class that's been marked as [Serializable] with a DeepClone method

MyClass copy = obj.DeepClone();
Neil