JavaScript EditorDhtml editor     Free javascript download 



Main Page

The way to declare delegates and events has changed from Managed Extensions for C++ to Visual C++ 2005.

The only change to the declarations of a delegate and a trivial event is the removal of the double underscore, as in the following sample. As these things go, this has proved to be completely non-controversial. That is, there have been no advocates for the retention of the double underscore, which everyone now seems to agree gave Managed Extensions a somewhat grotty feel.

In Managed Extensions:

В CopyCode imageCopy Code
__delegate void ClickEventHandler(int, double);
__delegate void DblClickEventHandler(String*);

__gc class EventSource {
   __event ClickEventHandler* OnClick;  
   __event DblClickEventHandler* OnDblClick;  
};

In the new syntax:

В CopyCode imageCopy Code
delegate void ClickEventHandler( int, double );
delegate void DblClickEventHandler( String^ );

ref class EventSource {
   event ClickEventHandler^ OnClick; 
   event DblClickEventHandler^ OnDblClick; 
};

Events (and delegates) are reference types, which is more apparent in the new syntax due to the presence of the hat (^). Events support an explicit declaration syntax as well as the trivial form. In the explicit form, the user specifies the add(), raise(), and remove() methods associated with the event. (Only the add() and remove() methods are required; the raise() method is optional.)

Under Managed Extensions, if the user chooses to provide these methods, she must not provide an explicit event declaration, although she must decide on a name for the event that is not present. Each individual method is specified in the form add_EventName, raise_EventName, and remove_EventName, as in the following example taken from the Managed Extensions specification:

В CopyCode imageCopy Code
// explicit implementations of add, remove, raise …
public __delegate void f(int);
public __gc struct E {
   f* _E;
public:
   E() { _E = 0; }

   __event void add_E1(f* d) { _E += d; }

   static void Go() {
      E* pE = new E;
      pE->E1 += new f(pE, &E::handler);
      pE->E1(17); 
      pE->E1 -= new f(pE, &E::handler);
      pE->E1(17); 
   }

private:
   __event void raise_E1(int i) {
      if (_E)
         _E(i);
   }

protected:
   __event void remove_E1(f* d) {
      _E -= d;
   }
};

The problems with this design are largely cognitive rather than functional. Although the design supports adding these methods, it is not immediately clear from looking at the above sample exactly what is going on. As with the Managed Extensions property and indexed property, the methods are shot-gunned across the class declaration. Slightly more unnerving is the absence of the actual E1 event declaration. (Once again, the underlying details of the implementation penetrate up through the user-level syntax of the feature, adding to the apparent lexical complexity.) It simply labors too hard for something that is really not all that complex. The new syntax hugely simplifies the declaration, as the following translation demonstrates. An event specifies the two or three methods within a pair of curly braces following the declaration of the event and its associated delegate type, as follows:

В CopyCode imageCopy Code
public delegate void f( int );
public ref struct E {
private:
   f^ _E; // yes, delegates are also reference types

public:
   E() {  // note the replacement of 0 with nullptr!
      _E = nullptr; 
   }

   // the new aggregate syntax of an explicit event declaration
   event f^ E1 {
   public:
      void add( f^ d ) {
         _E += d;
      }

   protected:
      void remove( f^ d ) {
         _E -= d;
      }

   private:
      void raise( int i ) {
         if ( _E )
            _E( i );
      }
   }

   static void Go() {
      E^ pE = gcnew E;
      pE->E1 += gcnew f( pE, &E::handler );
      pE->E1( 17 ); 
      pE->E1 -= gcnew f( pE, &E::handler );
      pE->E1( 17 ); 
   }
};

Although people tend to discount syntax as non-glamorous and trivial in terms of language design, it actually has a significant if largely unconscious impact on the user’s experience of the language. A confusing or inelegant syntax increases the hazardousness of the development process in much the same way that a dirty or fogged windshield increases that of driving. In the new syntax, we’ve tried to make the syntax as transparent as a highly polished, newly installed windshield.

See Also



JavaScript EditorDhtml editor     Free javascript download