![](https://secure.gravatar.com/avatar/5462e710e6931162784950ecae16f77d.jpg?s=120&d=mm&r=g)
Hi all - Looking at fixing a problem with events, I'm realizing that my original plan has a big hole in it :( Here's the situation: the framework requires that an event be implemented by providing an add_SomeEvent and a remove_SomeEvent method. However, the actual storage and mechanisms used to call the delegates registered via those special methods are completely up to the implementor of a class. When you write, for example, a class with an event in C# using the MS tools, you get: - add_* and remove_* methods - a private internal field to hold the delegate You do *not* get an automagic method to fire the event, because the class implementor is supposed to provide this if it appropriate (but may choose not to). The current Python.NET event stuff expects this setup, and it allows you to treat the event as a callable object - when you call the event, it tries to call that internal delegate. The problem is that its wrong :) According to everything I can find, a class is supposed to provide an 'OnSomeEvent' method to fire an event if it is appropriate for client code to fire the events of the class explicitly. If a class does not provide an 'OnSomeEvent' method, then it is assumed that it is not appropriate for the event to be fired by a client (and there is in fact no reliable way for the client to even try, since the dispatching to subscribers is purely internal to the class and could be done in arbitrary ways). I'm tempted to remove the ability to call event objects directly from Python, as this would match the convention and what you'd have to do in C# or VB, etc. (you'd call the OnSomeEvent method instead). The alternative would have to be doing some kind of automagical thing where we'd try lookup up an OnXXX if the usual private event field wasn't there, but that seems nasty... thoughts? Brian Lloyd brian@zope.com V.P. Engineering 540.361.1716 Zope Corporation http://www.zope.com
![](https://secure.gravatar.com/avatar/115def2d472ca3aa214a1eaccd0a8e30.jpg?s=120&d=mm&r=g)
Brian Lloyd wrote:
Hi all -
Looking at fixing a problem with events, I'm realizing that my original plan has a big hole in it :(
These moments are tragic but ... things like this happen. ... hopefully not too frequently :)
(snip)
The current Python.NET event stuff expects this setup, and it allows you to treat the event as a callable object - when you call the event, it tries to call that internal delegate.
The problem is that its wrong :) According to everything I can find, a class is supposed to provide an 'OnSomeEvent' method to fire an event if it is appropriate for client code to fire the events of the class explicitly. If a class does not provide an 'OnSomeEvent' method, then it is assumed that it is not appropriate for the event to be fired by a client (and there is in fact no reliable way for the client to even try, since the dispatching to subscribers is purely internal to the class and could be done in arbitrary ways).
I'm tempted to remove the ability to call event objects directly from Python, as this would match the convention and what you'd have to do in C# or VB, etc. (you'd call the OnSomeEvent method instead).
The alternative would have to be doing some kind of automagical thing where we'd try lookup up an OnXXX if the usual private event field wasn't there, but that seems nasty...
thoughts?
Hi Brian, to me it doesn't feel to be a good idea to call events directly because this would be something not intended with events in the CLR. As i see it, events associated with an object are to provide a mechanism for other(!) objects to get notified of some change in the objects state and only the object itself should control when this notification takes place. This is why the On<event> methods are protected. Their sole purpose is to give a subclass the chance to overwrite the event handling without registering a delegate. If a class wants to allow client code to trigger an event it should provide an appropriate method (or property) which changes the state of an object and then fires the corresponding event to notify who ever's interested. As far as I looked at the CLR classes I think this is the way they are designed. For example, Windows.Forms.Control: Click : OnClick : PerformClick Paint : OnPaint : Invalidate (or Refresh) GotFocus : OnGotFocus : Focus LostFocus : OnLostFocus : Focus The Focus method shows how important it may be to call the provided method instead of triggering an event directly. Calling GotFocus directly would do only half of the show. I don't know if there's a way to prevent python code from calling protected members of CLR objects from outside. If not, may be it possible to follow the common convention and make them visible under names beginning with an _. Michael
participants (2)
-
Brian Lloyd
-
Michael.Amrhein@t-online.de