Re: Consuming your own events.

Daniel Petersson <[email protected]> Wed, 30 Jan 2008 07:50:21 +0100
Newsgroups gmane.comp.windows.devel.dotnet.clr
Message-ID <E8FBCCA96548DD46A1AC748F17EEAD9C0E96F2ACDC@cefalo-mail01.cefalo.local>
Hi Sebastien,

In this case the guidelines are right and sadly you are wrong =)
Your proposed solution isn't at all bad; but it is an even more complex guideline then
the one provided by MS, and even worse it is only your guideline =( Here are a few fast comments:

1. the protected virtual OnTheEvent( ... ) shall only EVER be used to raise the event; no other logic.
If you implement other logic here, in a class designed for inheritance you are in trouble.

2. Cancelable events are just a hack, remember that an event is a multicast delegate. Using OnTheEvent( ... ) you can control if the event is raised. Sure you can get the invocation list and call the clients one at a time; but how do you handle the case where a client further down the list cancels the operation??? Do you compensate for it??? If so how???
Building a Before and After could work, but then you could as well Plain Old Callback interfaces (java/COM style) and really get down and dirty =)

3. OnTheEvent( ... ) notation or HandleTheEvent( ... ) is internal stuff, if they show up publicly then someone broke the encapsulation principle.

4. Using base classes are always pretty brittle; It is just simply very very very hard to design and implement a class correctly for inheritance.

Regards,
  Daniel


-----Original Message-----
From: Discussion of development on the .NET platform using any managed language [mailto:[email protected]] On Behalf Of Sebastien Lambla
Sent: den 29 januari 2008 11:50
To: [email protected]
Subject: Re: [DOTNET-CLR] Consuming your own events.

> the guideline clearly state that non-sealed classes that expose events
> should implement a:
> protected virtual void OnTheEvent( EventArgs e ) for every public
> event.

Guidelines are just that, guidelines. They're not always right, and over
time the get more wrong.

The problem with the OnXxx notation is that it's overloaded with meaning.
Some class libraries put the event raising on it, others use it for
handlers. The intent of the overriding mechanism can only be described in
the documentation, and calling base.OnXxx is up to the developer. It's in my
opinion quite a poor design.

If you want to cancel an event, have a CancelableEventArgs with a bool
Cancel property, raise it through the RaiseXxx method. Have all the handlers
in the form HandleXxx. Adopt the Xxxing / Xxxed notation to provide for
ordering. Provide an optional OnXxx that is called before the event and can
cancel it, having essentially the semantics of an event handler attached to
the instance of a type, something that is quite common in WPF where attached
events are docked to a type through the OnXxx method.

I find the code semantics of "ea.Cancel = true" much better than the
semantics of not calling the base class as a way to cancel an event.

If your object is in an undeterministic state if throwing when the event is
raised, so will it with overridden OnXxx that forgets to call the base class
implementation.

I've seen way too many issues all around the semantics of calling
base.OnXxx, where it is sometimes needed, sometimes not, and never visible
in the code, to find the common meme on event raising / handling to be
either sufficient or in any way accurate.

It's a bit like the Begin / End async handling where people were quite wrong
for years on the necessity to call End because the semantics were left to
documentation.


--
SerialSeb

===================================
This list is hosted by DevelopMentor?  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com

===================================
This list is hosted by DevelopMentorĀ®  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com