Handling Events in C#.NET

J

Joe Cool

OK, based on my research and personal experiance, here is how I code
events in C#.NET.

First, let's say that the event I need to code will return a custome
EventArgs object, so I define that class as:

public class MyCustomEventArgs : EventArgs
{
public MyCustomEventArgs(string myCustomEventProperty)
{
this.myCustomEventProperty = myCustomEventProperty;
}
public string myCustomEventProperty;
}

Next, in the class that needs to expose this property, I first declare
a delegate for the event:

public delegate void MyEventHandler(object sender, MyCustomEventArgs
ce);

Next, I define the public event:

public event MyEventHandler MyEvent;

Next I declare a special method that any other method or event handler
in the class can use to raise the event:

protected virtual void OnMyEvent(string myCustomEventProperty)
{
MyCustomEventArgs ce = new MyCustomEventArgs(myCustomEventProperty);

if (this.MyEvent != null)
{
this.MyEvent(this, ce);
}
}

Now to raise the event I can:

this.OnMyEvent("a string value");

Now, my question is this. The OnMyEvent method is not realy required
to raise this event. I could just as easily have:

MyCustomEventArgs ce = new MyCustomEvent();

ce.myCustromEventProperty = "a string value";
if (this.MyEvent != null)
{
this.MyEvent(this, ce);
}

From what I can tell, the OnMyEvent method is only useful if the event
needs to ber raised in more than one place in the class.

Is this a correct assumption? Or is there a reason to use the
OnMyEvent method even if the event will only be raised once in the
class?
 
J

Joe Cool

OK, based on my research and personal experiance, here is how I code
events in C#.NET.

First, let's say that the event I need to code will return a custome
EventArgs object, so I define that class as:

public class MyCustomEventArgs : EventArgs
{
public MyCustomEventArgs(string myCustomEventProperty)
{
this.myCustomEventProperty = myCustomEventProperty;
}
public string myCustomEventProperty;
}

Next, in the class that needs to expose this property, I first declare
a delegate for the event:

public delegate void MyEventHandler(object sender, MyCustomEventArgs
ce);

Next, I define the public event:

public event MyEventHandler MyEvent;

Next I declare a special method that any other method or event handler
in the class can use to raise the event:

protected virtual void OnMyEvent(string myCustomEventProperty)
{
MyCustomEventArgs ce = new MyCustomEventArgs(myCustomEventProperty);

if (this.MyEvent != null)
{
this.MyEvent(this, ce);
}
}

Now to raise the event I can:

this.OnMyEvent("a string value");

Now, my question is this. The OnMyEvent method is not realy required
to raise this event. I could just as easily have:

MyCustomEventArgs ce = new MyCustomEvent();

ce.myCustromEventProperty = "a string value";
if (this.MyEvent != null)
{
this.MyEvent(this, ce);
}

From what I can tell, the OnMyEvent method is only useful if the event
needs to ber raised in more than one place in the class.

Is this a correct assumption? Or is there a reason to use the
OnMyEvent method even if the event will only be raised once in the
class?

I also meant to ask, why is this OnMyEvent method a protected virtual
method?
 
J

Jeff Johnson

Note that the above is not thread-safe. Strictly speaking, there's no
need to make it thread-safe if you know for sure you're always accessing
the event in just one thread. But, it's simple enough to make the method
thread safe, and the default implementation for an event is itself
thread-safe so I always like to just go ahead and follow that pattern.

A thread-safe version of your method looks like this:

protected virtual void OnMyEvent(string myCustomEventProperty)
{
EventHandler<MyCustomEventArgs> handler = MyEvent;

if (handler != null)
{
handler(this, new MyCustomEventArgs(myCustomEventProperty));
}
}

By copying the current event delegate before performing any operations
with it, you ensure that it can't change from non-null to null before you
actually try to invoke it.

Cool! I saw that pattern somewhere and have been copying it ever since, but
I wasn't sure if it was a necessary thing to do or if the original writer
was just paranoid. An explanation of its usage makes me feel like I'm not
wasting my time anymore.

To Joe Cool: I know you were only giving sample code, but I certainly hope
that in your real code you don't actually have the word "event" anywhere in
your event name. It's silly and redundant, but unfortunately some people
actually put it in there.
 
P

Peter Morris

is there a reason to use the
OnMyEvent method even if the event will only be raised once in the
class?

I also meant to ask, why is this OnMyEvent method a protected virtual
method?

Your 2nd question answers your first one. Not only does creating the
On..... method save you from duplicating code in your class "if" you invoke
the method from more than one place, but by marking it protected virtual
means 2 things

01: A descendant class is able to call OnMyEvent (due to "protected"),
whereas it is not possible to invoke the event from a descendant class.
02: A descendant class is able to override (due to "virtual") the method and
change the behaviour.
 
J

Jeff Johnson

01: A descendant class is able to call OnMyEvent (due to "protected"),
whereas it is not possible to invoke the event from a descendant class.

Did you mean "a non-descendant class" at the end?
 
J

Joe Cool

Cool! I saw that pattern somewhere and have been copying it ever since, but
I wasn't sure if it was a necessary thing to do or if the original writer
was just paranoid. An explanation of its usage makes me feel like I'm not
wasting my time anymore.

To Joe Cool: I know you were only giving sample code, but I certainly hope
that in your real code you don't actually have the word "event" anywhere in
your event name. It's silly and redundant, but unfortunately some people
actually put it in there.

Yeah, I just used those names to remove any ambiguity. I never
actually code an event witht the word "Event" in its name, nor do I
code properties with the word "Property" as part its name.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top