I have a class with multiple EventHandlers (among other things):
public GameObject
{
public event EventHandler<EventArgs> Initialize;
public event EventHandler<EventArgs> BeginStep;
....
}
I want to be able to add a Clone()
function to GameObject, which returns an exact duplicate of the object it was called on. I tried doing it like this:
public GameObject Clone()
{
var clone = new GameObject()
{
Initialize = this.Initialize,
BeginStep = this.BeginStep,
};
}
But, it appears that it is making clone.BeginStep
point to the same object as this.BeginStep
instead of making a copy. So, how do I make a copy of an EventHandler object?
You don't need to worry about that. The EventHandler<EventArgs>
object is immutable so any change in the list of listeners in either object will cause that object to get a new EventHandler<EventArgs>
instance containing the updated invocation list. This change will not be present in the other GameObject
.
Try adding it with the += operator. I didn't even know it was possible to assign an event.
clone.Initialize += this.Initialize;
Also, all delegates are immutable value types, therefore you don't have to worry about them pointing to the same object - when you an operation like above, the whole delegate is copied (cloned, if you will).
It depends on whether your events are delegating to methods defined in the GameObject class or whether they delegate to to some other observer class instance.
If the events are handled in methods defined in your GameObject class and you want events in the clone to be handled by methods in your clone instance, you can get use reflection to get the method info from the original event handlers, create a new delegate using the cloned instance and the method name, and then assign the new delegate as the cloned event handler.
public GameObject Clone()
{
var clone = new GameObject();
foreach (var target in this.Initialize.GetInvocationList())
{
var mi = target.Method;
var del = Delegate.CreateDelegate(
typeof(EventHandler<EventArgs>), clone, mi.Name);
clone.Initialize += (EventHandler<EventArgs>)del;
}
return clone;
}
If the events are handled in a different class, then you don't need to do anything, but all event notifications for both the original instance and cloned instance willhave the same handlers. If that's not what you want then you'll need to change the event delegates after you clone.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With