473,503 Members | 2,136 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

IClonable

If I want to implement an IClonable interface, how can I copy the events
from my source object to the target "cloned" object?
Nov 15 '05 #1
5 3651
If I want to implement an IClonable interface, how can I copy the events
from my source object to the target "cloned" object?

class CloneableWithEvents : ICloneable
{
public event MyDelegate MyEvent;

public object Clone()
{
CloneableWithEvents clone = new CloneableWithEvents();
clone.MyEvent += MyEvent;
return clone;
}
}

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Nov 15 '05 #2

"Mattias Sjogren" <ma********************@mvps.org> wrote in message
news:uZ****************@TK2MSFTNGP10.phx.gbl...
If I want to implement an IClonable interface, how can I copy the events
from my source object to the target "cloned" object?

class CloneableWithEvents : ICloneable
{
public event MyDelegate MyEvent;

public object Clone()
{
CloneableWithEvents clone = new CloneableWithEvents();
clone.MyEvent += MyEvent;
return clone;
}
}


wouldn't

CloneableWithEvents clone = (CloneableWithEvents)this.MemberwiseClone();

be simpler? It catches private fields, including events(assuming they are
normal fields, not in a hash table or anything, and it will work when
overridden, the above method breaks when you inherit from it.

Mattias

--
Mattias Sjogren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Nov 15 '05 #3
Daniel,
wouldn't

CloneableWithEvents clone = (CloneableWithEvents)this.MemberwiseClone();

be simpler?
In this case, sure. But simpler isn't always better. :-) I didn't mean
to provide the definite way do handle this, just to show that it's
pretty straight forward and doesn't require any special magic.

It catches private fields, including events(assuming they are
normal fields, not in a hash table or anything, and it will work when
overridden,
MyEvent isn't virtual so you can't override it. ;-)

the above method breaks when you inherit from it.


If you expect your class to be inherited from (in code you don't
control) I would strongly suggest you avoid MemberwiseClone. You don't
know if the derived data can be safely be copied like that, or if it
for example references some unmanaged resource.

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Nov 15 '05 #4
thank's

"Mattias Sjögren" <ma********************@mvps.org> schrieb im Newsbeitrag
news:uZ****************@TK2MSFTNGP10.phx.gbl...
If I want to implement an IClonable interface, how can I copy the events
from my source object to the target "cloned" object?

class CloneableWithEvents : ICloneable
{
public event MyDelegate MyEvent;

public object Clone()
{
CloneableWithEvents clone = new CloneableWithEvents();
clone.MyEvent += MyEvent;
return clone;
}
}

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Nov 15 '05 #5
> If you expect your class to be inherited from (in code you don't
control) I would strongly suggest you avoid MemberwiseClone. You don't
know if the derived data can be safely be copied like that, or if it
for example references some unmanaged resource.


You're missing the point of MemberwiseClone then.

The correct way to clone a base-class object is as follows:

public virtual object Clone()
{
//perform shallow copies of all members, even derived ones
MyClass clone = (MyClass)MemberwiseClone();

//perform deep copies where required
clone.deepCopyValue = (ContainedClass)deepCopyValue.Clone();

//I usually disconnect any events here, actually
//since I don't usually want event handlers cloned

//finally
return clone;
}
This way any sub-classes of MyClass will automatically get a correct clone
of the base class. If the derived classes need a deep copy of anything
else, they can override Clone as follows:

public override object Clone() {
//allow base class to do its work, and deep copy anything it needs to
MySubClass clone = (MySubClass)base.Clone();

//if any of the derived members need to be deep-copied, do that here:
clone.collection = new MyCollection(collection);

return clone;
}

It's up to each class to deep-copy any members that it needs. If the
sub-class fails to do so, it's the fault of the sub-class. At least with
the base-class using MemberwiseClone, sub-classes don't need to override
Clone unless they need to provide further deep-copying. Many times,
shallow-copies are perfectly acceptable.

If you don't use this method, you either need to provide a means for
sub-classes to safely clone all of the members of the base class (by making
them protected, perhaps), or through the use of
copy-constructor-like-semmantics (which then require all sub-classes to
follow a pattern which isn't very intuative to most C# programmers).

Using any other method (especially methods where Clone isn't marked virtual)
makes it the job of every derived class to ensure that the base class is
cloned properly.

Using the method I've described makes it the job of each class to deep-copy
only the members that it needs to. Sub-classes need not worry about how to
clone the parent class. This helps versioning as well---in case the parent
class introduces new members that require deep copies that the child class
is not aware of.

It seems to me that NOT using MemberwiseClone is more fragile than using it.
Or am I missing some obvious better way to implement cloning? I know
copy-constructors can work, but it's not nearly as elegant as a virtual
Clone implemented with MemberwiseClone and further deep copying.

--Matthew W. Jackson
Nov 15 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
2083
by: AMerrell | last post by:
Hello, There is a C# funciton I'm trying to translate that clones some event handlers. public virtual object Clone() { ...... Instance of a Custom Collection ....... myCol.ItemAdded =...
2
3250
by: Dan | last post by:
I have an object that I want to add to an ArrayList. However, I don't know ahead of time how many objects I will need to add to the list. Therefore, I had built a function that created an instace...
7
3740
by: Tiësto | last post by:
Hi everybody. I know everyone has said to me that this doesn't exist but I'm going to try anyway. I have an instance of ClassA and I want to duplicate that instance, creating another one that is...
1
2318
by: oDDskOOL | last post by:
I realized today that the Hashtable.Clone only produces a shallow copy... that makes me go mad that M$ doesn't even provide a deep copy ctor for the Hashtable class ! mighty tech ducks might...
14
2695
by: Arne | last post by:
In C++ we have a copy constructor. What is the equivalent in .Net? Would that be a clone method?
2
19442
by: Nathan | last post by:
I'm working with Clone() for the first time, and noticed that you have to unbox the Clone of an object that implements ICloneable: MyObject var1 = new MyObject(); // Where MyObject implements...
6
1823
by: Larry Minton | last post by:
Is there a C++ method comparable to the vb.net TryCast function? I had hopes for Convert::ChangeType, but that didn't work. For a scripting engine, the user is specifying to retrieve an...
2
10083
by: bonk | last post by:
I have come across the need to distinguish between the creation of a deep and a shallow copy and with great interest I have read this article: ...
15
2698
by: Gustaf | last post by:
Using VS 2005. I got an 'IpForm' class and an 'IpFormCollection' class, containing IpForm objects. To iterate through IpFrom objects with foreach, the class is implemented as such: public class...
0
7204
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7091
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7282
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7342
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
6998
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
7464
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
4680
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3171
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
1
741
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.