define event

Posted by jmls on 18-Feb-2010 15:43

Using the new DEFINE EVENT stuff in 10.2B, all is good.

Until now.

class foo:

DEF PUBLIC EVENT NewMessage SIGNATURE VOID (p_Message AS LONGCHAR).

Method meth:

newMessage:Publish("data").

end method.

class foo2 inherits foo:

Method override meth:

do some more stuff

newMessage:Publish("data").

end method.

this is not allowed ! Why ? How can I declare an event in a base class, and then publish that event in a class that inherits that base class ?

All Replies

Posted by whenshaw on 18-Feb-2010 15:57

Hi Julian,

You can call Publish on an event only in the class in which it's defined. In order to get the event published from outside the defining class, add a PublishNewMessage method (name is not significant -- it would just be a method) to your base class, give it the appropriate access modifier (in this case it would only need to be PROTECTED) and call the Publish in that. So your override would look like:

Method override meth:

do some more stuff

PublishNewMessage:Publish("data").

end method.

--Wayne

Posted by whenshaw on 18-Feb-2010 16:03

Whoops, sorry, the override would look like this (not PublishNewMessage:Publish... :

Method override meth:
do some more stuff
PublishNewMessage("data").
end method.
Posted by Thomas Mercer-Hursh on 18-Feb-2010 16:07

Wayne has given you a functional answer, but let me supplement that by saying that there is a school of thought which suggests that you shouldn't override methods in that way.  Yes, I know it works in many cases and lots of people do it, but there is something to be said for a clear separation of responsibility between classes, even if one is a subclass of the other.  I.e., if it is the responsibility of the parent to know about and publish the event, then the parent should publish the event.  So, put the publish event code in the parent, where it can be used by all subclasses, and put the other stuff into the subclasses.  You will have a cleaner separation between the two without the override.

Posted by Admin on 18-Feb-2010 23:22

Isn't it cool, that there's only exactly one class that's allowed to publish that event - the base class?

We use Microsoft's .NET pattern for all our events (frontend and backend). So a developer working with GUI for .NET does not need to cope with two different patterns for events.

Let's say we have an event XyzHasHappened. Then the event will have a specialized event argument class: XyzHasHappenedEventArgs. This argument class would have your longchar parameter as a property. You never know, when the event need's a second or even third parameter. And adding additional properties to the ...EventArg class is easier than adding another parameter to all event handler methods. We use the ...EventArg parameter also for events that don't need parameters as of today.

Then there's another parameter, called sender of type Progress.Lang.Object, System.Object or even the actual class itself (depending on if we want to allow similar events from classes being handled by the same event handler or not). Actually the sender is the first parameter - I bet you've seen that before

The one and only place that published the event is a method called OnXyzHasHappened, expecting a parameter e AS XyzHasHappenedEventArgs. When someone here uses the Publish method of an event outside the OnXyzHasHappened method we do consider that a mistake that needs to be fixed.

The method has 3 purposes:

1. Perform pre and post condition checks: Is the object in a state that allows publishing the event? Is the parameter object e valid and makes sense?

2. Publishes the event THIS-OBJECT:XyzHasHappened:Publish (THIS-OBJECT, e).

3. This method is considered the "internal" event handler for child classes. Child classes may override this class and define exactly if they want to perform action before or after all other subscribers (external subscribers). So in a child class we don't SUBSCRIBE to the event, we override the On... method.

In many cases we implement a before and after event. In those cases we follow Infragistics naming pattern of prefixing the event with Before and After, not Microsofts "ing" or "ed" verbs. When the Before Event is cancellable, we add an Cancel property to the EventArg.

So the fact the the Publish method is private to the class defining the event suits very well with our (and .NET's) coding standards.

This thread is closed