Style Question: Event handling

W

Wavemaker

The canonical way of declaring delegates for events is to include a
parameter representing the sender as well as an EventArgs derived class
(or EventArgs itself) as the second parameter representing the data that
accompanies the event. For example:

public delegate void MessageReceivedHandler(object sender,
MessageReceivedArgs e);

// ...

public event MessageReceivedHandler MessageReceived;

Event handlers are usually declared as private or protected. Using the
above example, the method for handling the MessageReceived event would
look like this:

private void HandleMessageReceived(object sender,
MessageReceivedEventArgs e)
{
// ...
}

A few of questions:

Would it be considered bad style to make the event handler method
public?

The reason I ask is that it would be nice to have a third party wire up
objects via events and event handlers and let the objects talk to each
other without having to know anything about each other other than the
delegate signature.

// Class A has an event of the MessageReceivedHandler type.
A a = new A();

// Class B has a public event handler matching the
MessageReceivedHandler signature.
B b = new B();

a.MessageReceived +=
new MessageReceivedHandler(b.HandleMessageReceived);

Assuming this is ok so far, I think it would be nice to change the name
of the event handler from HandleMessageReceived to something a little
less verbose and more straight forward. Ideally the method's name would
reflect what it does, say in this example it sends the event's data
somewhere. So let's call it Send.

a.MessageReceived += new MessageReceivedHandler(b.Send);

Since the Send method is public, it can be called directly instead of in
response to an event. However, the sender parameter may not be necessary
and just adds noise to the call, so let's get rid of it. Also, instead
of the EventArgs derived class parameter, let's pass the data directly.
Say in this case it is some fictional Message class object. So we now
have this:

public delegate void MessageReceivedHandler(Message msg);

// ...

// Declared in class A.
public event MessageReceivedHandler MessageReceived;

A a = new A();
B b = new B();
Message msg = new Message();

a.MessageReceived += new MessageReceivedHandler(b.Send);

// Event handler called directly.
b.Send(msg);

I realize that I've gone further and further away from Microsoft's .NET
coding guidlines for events. However, my point is that it would be nice
to use the event/delegate mechanism to set up a kind of pipe and filter
architecture between objects and that the guidlines may be adding extra
noise that isn't necessary in this case.

I don't ignore guidelines lightly, and was just wondering what
everyone's thought on this was. At which point do you draw the line?
When do you think it's appropriate to bypass the guidelines? Is it
appropriate in the case I described above?
 
S

Scott Roberts

Would it be considered bad style to make the event handler method
public?

I don't see why (why it would be bad, that is).
Since the Send method is public, it can be called directly instead of in
response to an event. However, the sender parameter may not be necessary
and just adds noise to the call, so let's get rid of it.

Here I'm getting skeptical. The "sender" parameter may seem unnecessary now,
but will it ever be necessary at some time in the future? You're limiting
your functionality in that the object handling the event can now never know
what object generated the event.
Also, instead
of the EventArgs derived class parameter, let's pass the data directly.
Say in this case it is some fictional Message class object.

This also has a bad smell. I would derive from EventArgs and add a property
to carry the Message object.
I realize that I've gone further and further away from Microsoft's .NET
coding guidlines for events. However, my point is that it would be nice
to use the event/delegate mechanism to set up a kind of pipe and filter
architecture between objects and that the guidlines may be adding extra
noise that isn't necessary in this case.

I don't ignore guidelines lightly, and was just wondering what
everyone's thought on this was. At which point do you draw the line?
When do you think it's appropriate to bypass the guidelines? Is it
appropriate in the case I described above?

The question I would ask is this: When you hire a new programmer and assign
them a task involving working with what you've described, how long will it
take them to "get it"? It seems pretty straight-forward to me, but it is
different enough that it is still foreign.

If it were me, I would tend to stick with the "recommended" method and have
two public methods:

public void Send(Message msg)
{
}

public void HandleMessageEvent(object sender, MessageEventArgs e)
{
Send(e.Message);

// Will I ever need to send a response back to "sender"?
}

Now you can essentially call "Send()" either way (directly or via an event)
and it's pretty clear what's going on either way.
 
W

Wavemaker

Scott Roberts said:
in message:


The question I would ask is this: When you hire a new programmer and
assign them a task involving working with what you've described, how
long will it take them to "get it"? It seems pretty straight-forward
to me, but it is different enough that it is still foreign.

If it were me, I would tend to stick with the "recommended" method and
have two public methods:

public void Send(Message msg)
{
}

public void HandleMessageEvent(object sender, MessageEventArgs e)
{
Send(e.Message);

// Will I ever need to send a response back to "sender"?
}

Now you can essentially call "Send()" either way (directly or via an
event) and it's pretty clear what's going on either way.

Ah, the best of both worlds. Honestly, I hadn't thought of that before.
Thanks for a clear and helpful response.
 

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

Top