what's the use of MemberwiseClone() ?

  • Thread starter Thread starter Christian
  • Start date Start date
C

Christian

Hi,

what's the use of MemberwiseClone() ? It only performs a shalow copy as does
the assignment of one object to another :
myObj1 = myObj2

I don't see the benefit of this function.

Can anybody help me ?

thnx
Chris
 
When you implement the Clone method of the ICloneable interface,
MemberwiseClone will give you the shallow copy, and it's up to you to
provide the code for the deep copy.
 
Christian said:
what's the use of MemberwiseClone() ? It only performs a shalow copy as does
the assignment of one object to another :
myObj1 = myObj2

No, there's a big difference.

myObj1 = myObj2.Clone();

- Now the values of myObj1 and myObj2 are references to different
objects. They happen to have the same values at this point in time, but
they needn't in the future.


myObj1 = myObj2;

- Now the values of myObj1 and myObj2 are references to the same
object. Any change made to the object via either variable is visible
via the other variable.

Here's a small test program to show the difference:

using System;

public class Test : ICloneable
{
string name;
public string Name
{
get { return name; }
set { name = value; }
}

static void Main()
{
// Set up the initial object
Test t1 = new Test();
t1.Name = "Bob";

Console.WriteLine ("Using Clone()");
Test t2 = (Test)t1.Clone();
t2.Name = "Fred";
Console.WriteLine ("t1.Name={0}", t1.Name);
Console.WriteLine ("t2.Name={0}", t2.Name);

Console.WriteLine ("Using assignment");
Test t3 = t1;
t3.Name = "Fred";
Console.WriteLine ("t1.Name={0}", t1.Name);
Console.WriteLine ("t3.Name={0}", t3.Name);
}

public object Clone()
{
return MemberwiseClone();
}
}
 
Note that you can change the class being cloned (add/remove members) and a
recompilation will "do the right thing" for the MemberwiseClone. This is
much more convenient than writing out the assignment statements for each
member and then having to change them when/if you redesign the object.

Even if you want a deep copy, doing the MemberwiseClone first will do the
job for the value type objects and you need only implement the deep copy for
the rest. Many of these, like array types, can be copied by applying
MemberwiseClone to each of them, into the clone. In fact, you can implement
a deep copy with a set of MemberwiseClone statements as you go deeper into
the object's structure.
 
Are we talking reference types or value types here?

If reference types, your example doesn't perform a shallow object copy, it
copies one reference into/over another. After your example, you have two
reference variables, both referring to the same object (or both null
references).

If value types, then yes it is doing the same thing.

MemberwiseClone is a useful starting point when implementing ICloneable. It
gives you a new object (not just another reference to an existing one). You
can then begin to modify that new object as per that particular objects copy
semantics.

Hope that helps,

Stu
 
Even if you want a deep copy, doing the MemberwiseClone first will do the
job for the value type objects and you need only implement the deep copy for
the rest.

Now that you mention it, I've recently run into a problem here -- you
can't use this method to duplicate readonly fields because Clone is
not a constructor.

My workaround is using a traditional copy constructor but this in turn
means I can't use MemberwiseClone because it can't duplicate another
object into this object, only the other way round...

Is there any secret way to overwrite readonly fields, short of
reflection?
 
Christoph Nahr said:
Now that you mention it, I've recently run into a problem here -- you
can't use this method to duplicate readonly fields because Clone is
not a constructor.

My workaround is using a traditional copy constructor but this in turn
means I can't use MemberwiseClone because it can't duplicate another
object into this object, only the other way round...

Is there any secret way to overwrite readonly fields, short of
reflection?

No, have you reconsidered your usage of readonlys? In most cases it doesn't
seem that a readonly is needed for somethign that is so dynamic that a clone
would have to have different values.
 
No, have you reconsidered your usage of readonlys? In most cases it doesn't
seem that a readonly is needed for somethign that is so dynamic that a clone
would have to have different values.

Well, the readonly field is typically some kind of collection, and the
collection elements do have to change for the clone, but I never
nullify or re-allocate the collection once it's created. Declaring
the collection object readonly was a convenient way to ensure that.
 
Christoph Nahr said:
Well, the readonly field is typically some kind of collection, and the
collection elements do have to change for the clone, but I never
nullify or re-allocate the collection once it's created. Declaring
the collection object readonly was a convenient way to ensure that.

Ahh yes, I see. That certainly is a jam. Unfortunatly there is nothign that
can be done outside of copy constructors or reflection. Copy constructors
work to an extent but they dont quite fit into the .NET model and end up
with some ugly trade offs, perhaps relaxing the restrictions on the
ICloneable.Clone would do the job, but that is unfortunatly something we
can't do..
 
Back
Top