Click here to Skip to main content
Licence 
First Posted 19 Apr 2004
Views 36,737
Bookmarked 19 times

Events and Clones

By | 19 Apr 2004 | Article
Care needs to be taken when using Events and Clones.

Introduction

When using C# Events and MemberwiseClone, you can end up with some undesirable side effects. You can unwittingly end up leaking memory and/or get weird behavior. This article describes the problem with events and clones and gives a guideline on how to avoid these problems.

The Problem with Events and MemberwiseClone

If you use MemberwiseClone, it will clone any event the object has. This means the newly cloned object will fire off events to whatever objects were registered with the object you cloned from. This tends to be undesirable for a number of reasons:

  • The object that registered an interest in receiving events from the original object is now getting events from the newly cloned object also.
  • Because the object that registered for an event doesn't know about the newly cloned object, it doesn't know to deregister its interest from the cloned object.
  • Because events hold references to objects, it can cause objects to hang around in memory after you think you have killed all references to that object

Another thing to keep in mind about Events is that if you register your interest twice, you will have to deregister your interest twice before you will stop receiving events. To stop this, you can do a deregister before registering. If you hadn't registered before, the deregistration will do nothing. Then add your registration, if you had registered before, it will delete your registration then re-add it. E.g.

Owner.TheEvent -=new EventOwner.Handler(HandleIt);
Owner.TheEvent +=new EventOwner.Handler(HandleIt);

A Solution to the problem

Simplest solution is not to use MemberwiseClone when you have an object with events. Instead, you can use CopyFrom as the following example shows:

public void CopyFrom(ObjectWithEvent anObject)
{
    // copy members, but not events....
}

object ICloneable.Clone()
{
    return Clone();
}

public ObjectWithEvent Clone()
{
    ObjectWithEvent clone = new ObjectWithEvent();
    clone.CopyFrom(this);
    return clone;
}

The disadvantage of this is that you have to explicitly copy each field in your class inside your CopyFrom. Each time you add fields to your class, you also have to remember to update the CopyFrom. However, a further improvement is to use reflection to do the copy and recognize any events and not copy them.

Another thing to keep in mind with objects that register an interest in an event and also use CopyFrom is that they need to deregister their interest in events before copying from the other object. Once you have copied from the other object, you then re-register your interest. If you fail to do this, you will start receiving events from two objects.

public void CopyFrom(MyType anotherType)
{
    EventOwner.TheEvent -=new EventOwner.Handler(HandleIt);
    EventOwner = anotherType.EventOwner;
    EventOwner.TheEvent +=new EventOwner.Handler(HandleIt);
}

It can also be worth writing a Dispose method that deregisters your interest in Events. If you don't do this, the object that fires events will maintain a reference to your object and keep it alive. If the object that fires the event lasts for the application's lifetime, this can cause what seems to be a memory leak. It is also useful for the object firing events to know that all objects interested in its events are gone. E.g.

public void Dispose()
{
    Owner.TheEvent -=new EventOwner.Handler(HandleIt);
}

History

  • 25th February 2004 - Created.
  • 15th April 2004 - Turned into CodeProject article.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Keith Nicholas

Web Developer

New Zealand New Zealand

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
QuestionCLone windows Pinmembermesiasrojo0:43 12 Aug '11  
GeneralDo not use MemberwiseClone Pinsussdvemil21:02 20 Apr '04  
GeneralAnother approach Pinmemberleppie7:20 20 Apr '04  
GeneralCode Pinmemberalper1:53 20 Apr '04  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120517.1 | Last Updated 20 Apr 2004
Article Copyright 2004 by Keith Nicholas
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid