Creating a copy of an object in C# [duplicate]
Please have a look at the code below (excerpt from a C# book):
public class MyClass
{
public int val;
}
public struct myStruct
{
public int val;
}
public class Program
{
private static void Main(string[] args)
{
MyClass objectA = new MyClass();
MyClass objectB = objectA;
objectA.val = 10;
objectB.val = 20;
myStruct structA = new myStruct();
myStruct structB = structA;
structA.val = 30;
structB.val = 40;
Console.WriteLine("objectA.val = {0}", objectA.val);
Console.WriteLine("objectB.val = {0}", objectB.val);
Console.WriteLine("structA.val = {0}", structA.val);
Console.WriteLine("structB.val = {0}", structB.val);
Console.ReadKey();
}
}
I understands it produces the output below:
objectA.val = 20
objectB.val = 20
structA.val = 30
structB.val = 40
The last two lines of the output I have no problem with, but the first two tell me that objectA
and objectB
are pointing to the same memory block (since in C#, objects are reference types).
The question is how do make objectB
, a copy of objectA
so that it points to a different area in memory. I understand that trying to assign their members may not work since those members may be references, too. So how do I go about making objectB
a completely different entity from objectA
?
You could do:
class myClass : ICloneable
{
public String test;
public object Clone()
{
return this.MemberwiseClone();
}
}
then you can do
myClass a = new myClass();
myClass b = (myClass)a.Clone();
N.B. MemberwiseClone()
Creates a shallow copy of the current System.Object.
There is no built-in way. You can have MyClass implement the IClonable
interface (but it is sort of deprecated) or just write your own Copy/Clone method. In either case you will have to write some code.
For big objects you could consider Serialization + Deserialization (through a MemoryStream), just to reuse existing code.
Whatever the method, think carefully about what "a copy" means exactly. How deep should it go, are there Id fields to be excepted etc.
The easiest way to do this is writing a copy constructor in the MyClass class.
Something like this:
namespace Example
{
class MyClass
{
public int val;
public MyClass()
{
}
public MyClass(MyClass other)
{
val = other.val;
}
}
}
The second constructor simply accepts a parameter of his own type (the one you want to copy) and creates a new object assigned with the same value
class Program
{
static void Main(string[] args)
{
MyClass objectA = new MyClass();
MyClass objectB = new MyClass(objectA);
objectA.val = 10;
objectB.val = 20;
Console.WriteLine("objectA.val = {0}", objectA.val);
Console.WriteLine("objectB.val = {0}", objectB.val);
Console.ReadKey();
}
}
output:
objectA.val = 10
objectB.val = 20
There's already a question about this, you could perhaps read it
Deep cloning objects
There's no Clone() method as it exists in Java for example, but you could include a copy constructor in your clases, that's another good approach.
class A
{
private int attr
public int Attr
{
get { return attr; }
set { attr = value }
}
public A()
{
}
public A(A p)
{
this.attr = p.Attr;
}
}
This would be an example, copying the member 'Attr' when building the new object.
精彩评论