X++, C# Comparison: Event [AX 2012]
Updated: May 19, 2010
Applies To: Microsoft Dynamics AX 2012 R3, Microsoft Dynamics AX 2012 R2, Microsoft Dynamics AX 2012 Feature Pack, Microsoft Dynamics AX 2012
There are some differences in how X++ and C# implement the event design pattern. For more information, see Event Terminology and Keywords.
There are differences in the way delegates are used for events in X++ versus C#.
|
Item |
X++ |
C# |
Comment |
|---|---|---|---|
|
delegate |
In X++, a delegate can be declared only as a member on a class. A delegate cannot be a member on a table. All delegates are instance members of their class, not static members. No access modifier can be used on a delegate declaration, because all delegates are protected members. Therefore, the event can be raised only by code within the same class where the delegate is a member. However, the one exception to the private nature of a delegate is that code outside their class can operate on the delegates by using the += and -= operators. |
In C#, each delegate is a type, just as every class is a type. A delegate is declared independently of any class. Without the event keyword, you can have a delegate as a parameter type on a method, just as you can have a class as a parameter type. You can construct an instance of a delegate to pass in for the parameter value. |
In X++, each class is a type, but no delegate is a type. You cannot construct an instance of a delegate. No delegate can be a parameter for a method. But you can create a class that has a delegate member, and you can pass instances of the class as parameter values. For more information, see X++ Keywords. |
|
event |
In X++ code, an event is one of the following:
There is no event keyword in X++.
|
In C#, the event keyword is used to declare a delegate type as a member of a class. The effect of the event keyword is to make the delegate protected, yet still accessible for the += and -= operators. You can subscribe event handler methods to an event by using the += operator. A delegate can be useful without the event keyword, as a technique for passing a function pointer as a parameter into a method. |
The automatic events that occur before the start of a method, and after the end of a method, can be subscribed to only by using the AOT. |
|
+= and -= operators |
In X++, you use the += operator to subscribe methods to a delegate. The -= operator unsubscribes a method from a delegate. |
In C#, you use the += operator to subscribe methods to an event, or to a delegate that is not used with the event keyword. |
The delegate contains a reference to all the objects that have methods subscribed to the delegate. Those objects are not eligible for garbage collection while delegate holds those references. |
|
eventHandler |
In X++, the eventHandler keyword is required when you use either the += or -= operator to subscribe or unsubscribe a method from a delegate. |
System.EventHandler is a delegate type in the .NET Framework. |
This term is used differently in X++ than it is in C# or the .NET Framework. For more information, see X++ Keywords. |
This section contains an X++ code example for the event design pattern. It also contains a C# code sample for the same design pattern.
X++ Example
The important things to notice in the X++ example are the following:
-
The XppClass has a delegate member that is named myDelegate.
Note The AOT contains a node for the delegate. The node is located at AOT > Classes > XppClass > myDelegate. Several event handler nodes can be located under the myDelegate node. Event handlers that are represented by nodes in the AOT cannot be removed by the -= operator during run time.
-
The {} braces at the end of the delegate declaration are required, but they cannot have any code in them.
-
The XppClass has two methods whose parameter signatures are compatible with the delegate. One method is static.
-
The two compatible methods are added to the delegate with the += operator and the eventHandler keyword. These statements do not call the event handler methods, the statements only add the methods to the delegate.
-
The event is raised by one call to the delegate.
-
The parameter value that passed in to the delegate is received by each event handler method.
-
The short X++ job at the top of the example starts the test.
// X++
// Simple job to start the delegate event test.
static void DelegateEventTestJob()
{
XppClass::runTheTest("The information from the X++ job.");
}
// The X++ class that contains the delegate and the event handlers.
class XppClass
{
delegate void myDelegate(str _information)
{
}
public void myEventSubscriberMethod2(str _information)
{
info("X++, hello from instance event handler 2: " + _information);
}
static public void myEventSubscriberMethod3(str _information)
{
info("X++, hello from static event handler 3: " + _information);
}
static public void runTheTest(str _stringFromJob)
{
XppClass myXppClass = new XppClass();
// Subscribe two event handler methods to the delegate.
myXppClass.myDelegate += eventHandler
(myXppClass.myEventSubscriberMethod2);
myXppClass.myDelegate += eventHandler
(XppClass::myEventSubscriberMethod3);
// Raise the event by calling the delegate one time,
// which calls all the subscribed event handler methods.
myXppClass.myDelegate(_stringFromJob);
}
}
The output from the previous X++ job is as follows:
|
X++, hello from static event handler 3: The information from the X++ job. X++, hello from instance event handler 2: The information from the X++ job. |
C# Sample
This section contains a C# code sample for the event design pattern of the previous X++ sample.
// C# using System; // Define the delegate type named MyDelegate. public delegate void MyDelegate(string _information); public class CsClass { protected event MyDelegate MyEvent; static public void Main() { CsClass myCsClass = new CsClass(); // Subscribe two event handler methods to the delegate. myCsClass.MyEvent += new MyDelegate (myCsClass.MyEventSubscriberMethod2); myCsClass.MyEvent += new MyDelegate (CsClass.MyEventSubscriberMethod3); // Raise the event by calling the event one time, which // then calls all the subscribed event handler methods. myCsClass.MyEvent("The information from the C# Main."); } public void MyEventSubscriberMethod2(string _information) { Console.WriteLine("C#, hello from instance event handler 2: " + _information); } static public void MyEventSubscriberMethod3(string _information) { Console.WriteLine("C#, hello from static event handler 3: " + _information); } }
The output from the previous C# sample is as follows:
|
>> CsClass.exe C#, hello from instance event handler 2: The information from the C# Main. C#, hello from static event handler 3: The information from the C# Main. |
Microsoft Dynamics AX has other event systems that apply only to items in the AOT. For more information, see Event Handler Nodes in the AOT.
Announcements: New book: "Inside Microsoft Dynamics AX 2012 R3" now available. Get your copy at the MS Press Store.