Events

From The Oxygene Language Wiki
Jump to: navigation, search

This is a Language topic about Oxygene
 

Language Topics Introduction | Structured Overview | Grammar | Keywords | Functions



An event is a type member that consumers of the class can use to add, remove and optionally raise event handlers.

Events are always delegate types. From within the class, the event can be used like a plain delegate variable, but from the outside consumers can only add or remove handlers they know about.

Oxygene also provides a "raise" method that makes it possible to invoke an event externally.

By default, the variable and the accessor methods are compiler generated. Optionally, the member or add/remove/raise accessors can be stated explicitly.


Syntax

type
  MyDelegate = delegate (Sender: Object; Args: EventArgs);
  MyInterface = interface
    event MyEvent: MyDelegate;
    event MyRaiseEvent: MyDelegate raise;
  end;

  MyClass = class(MyInterface)
  private
    fMember: MyDelegate;
    method AddExplicitEvent(param: MyDelegate);
    method RemoveExplicitEvent(param: MyDelegate);
    method RaiseExplicitEvent(sender: Object; Args: EventArgs);
  public
    event MyEvent: MyDelegate delegate fMember;
    event MyRaiseEvent: MyDelegate raise; // implicit field. Also works without the raise.
    event ExplcitEvent: MyDelegate add AddExplicitEvent remove RemoveExplicitEvent raise RaiseExplicitEvent;
  end;


method MyClass.AddExplicitEvent(param: MyDelegate);
begin
  fMember := MyDelegate(&Delegate.Combine(fMember, param));
end;

method MyClass.RemoveExplicitEvent(param: MyDelegate);
begin
  fMember := MyDelegate(&Delegate.Remove(fMember, param));
end;

method MyClass.RaiseExplicitEvent(sender: Object; Args: EventArgs);
begin
  if assigned(fMember) then 
    fMember(sender, Args);
end;


Adding/Removing Delegates

In cases where you want to provide your own logic for adding/removing delegates to and from the event, the following extended syntax can be used:

type
  TMyClass = class(...)
  private
    fMyEvent: EventHandler;
    method AddMyEvent(aValue: EventHandler);
    method RemoveMyEvent(aValue: EventHandler);
  public
    event MyEvent: EventHandler add AddMyEvent remove RemoveMyEvent;
  end;

With this syntax, the two specified add and remove methods must conform to the syntax above, they must be procedures and take only one parameter, the matching delegate type. If either is provided, both "add" and "remove" must be specified.

Raise

The raise keyword on an event can be used to allow external classes to invoke the event handler. If present, it creates an internal method called fire_EventHandlerName with the signature of the delegate. Inside this method, code is generated to check if the event is assigned and - if it is - invoke it.

It is also possible to provide a custom raise method implementation.

When the raise keyword is set on an event, all calls to the events inside the class will use the raise method (if raise is not specified (default), the invoke method on the fMyEvent will be called inline). Because of this, there is no need to check for nil when there is a raise keyword involved.

Like the add/remove accessors, it is possible to change the visiblity of the raise method, for example protecting it, so only subclasses can call it.

Syntax Examples:

type
  MyEventTest = class
  private
    var f: EventHandler;
    method add_Event(e: EventHandler);
    method remove_Event(e: EventHandler);;
    method raise_Event(o: Object; e: EventArgs); 
  public
    event ev1: EventHandler;
    event ev2: EventHandler raise;
    event ev2: EventHandler protected raise;  // descendants can raise
    event ev3: EventHandler delegate f;
    event ev4: EventHandler delegate f raise;
    event ev5: EventHandler add add_event remove remove_event raise raise_event; // custom methods
  end;

When a non-private raise method is defined, the event can be invoked from outside the class, according to the visibility, through its name:

MyObject.MyEvent();

When consuming classes from languages that do not support using raise event invoking (such as C# and VB), the internal fire_myevent() method can be called directly.

Attributes

When using a property with an implicit field (no add/remove/delegate keyword), you can apply attributes to the auto generated fields with the var: prefix. See Attribute Scopes for more information.


See Also

Personal tools
Namespaces

Variants
Actions
Navigation
Getting Started
Sections
If you know
More
Toolbox