X++ Language Syntax is Stricter in Microsoft Dynamics AX 2012

Applies To: Microsoft Dynamics AX 2012 R3, Microsoft Dynamics AX 2012 R2, Microsoft Dynamics AX 2012 Feature Pack, Microsoft Dynamics AX 2012

Starting in Microsoft Dynamics AX 2012, the syntax rules for X++ are stricter than in previous versions of the product. This topic describes the syntax changes.

Table of X++ Syntax Changes

The following table displays a list of syntax changes that start in Microsoft Dynamics AX 2012.

Area

Syntax rule

Before Microsoft Dynamics AX 2012

Starting with Microsoft Dynamics AX 2012

Escape

The backslash character \ is rejected by the compiler for unrecognized escapes

The compiler used to accept "31\12\2002", but during run time the literal string was interpreted as a different value.

Now the following X++ statement is rejected by the compiler:

str myDateString = "31\12\2002";

The proper syntax is "31\\12\\2002".

Exceptions

Retry is no longer allowed outside of a catch block

It was possible to write the retry keyword outside of a catch block. This caused the program to end when the retry was reached during runtime.

Now retry can occur only inside a catch block. For more information, see Exception Handling with try and catch Keywords.

Exceptions

Now you can throw and catch only int values

It was possible to throw scalar expressions like strings and dates, such as throw "hello world";, and get no compile error. At runtime this was catch-able by a catch block that was not decorated with any specific value, such as catch {print("Catch worked.");}.

Now the only expression you can put on the throw keyword is an int.

Often the best thing to throw is Global::error("Explanation");. Often the best thing to catch is an element of the Exception enum. For more information, see Exception Handling with try and catch Keywords.

Inheritance

Downcasting can now be explicit.

Note

It is good programming practice to avoid implicit downcasts.

It was possible to assign a base object to a derived object with the simple assignment operator, which is the equals sign (=). The compiler accepted these assignments, but during run time any misuse of an improper downcast assignment caused an error.

Now all downcasts can be explicit. This is accomplished with the new as expression operator. Explicit downcasting with the as keyword is illustrated by the following code example, in which ThingClass extends Object:


 ThingClass myThing = new ThingClass(); 
 Object myObject = myThing; 
 myThing = myObject as ThingClass; // Explicit downcast, good.

For more information, see Expression Operators: Is and As for Inheritance.

Inheritance

Override of a base method cannot be less accessible than the base method

It was possible to have a base method be decorated with protected and yet have an override of that method be private.

Now when a base method is protected, the override method must be either protected or public, and the override method cannot be private. For more information, see Method Access Control.

Inheritance

Override of a base method must have the exact same return type and parameter signature as the base method

Suppose a base class had a method that inputs a parameter of the Common table, which is the base of all tables. In a derived class it was possible to override the method to instead input MyTable.

Now the parameter signatures of the base method and its override method must match exactly. Also, the return types must match exactly. For more information, see Overriding a Method.

Interfaces

Implementation of an interface method must match the parameter signature exactly

Suppose an interface had a method that input a parameter of an int. In a class that implements the interface, it was possible to write the method with a parameter of a str.

Now the parameter signatures of the method must exactly match between the interface and the implementation of the method on a class. Also, the return types must match exactly. For more information, see Interfaces Overview.

Interfaces

A non-abstract base class that implements an interface cannot rely on a derived class for that implementation

When a base class implements an interface, it was possible for the class to not implement the methods of the interface if a derived class implemented the methods. The only limitation was that the new constructor method could not be called on the class.

Now the compiler requires that every class that implements an interface must have or inherit a complete implementation of every method of the interface. For more information, see X++, C# Comparison: Object Oriented Programming.

Modifiers

The static modifier should not be applied to an interface

It was possible to write static interface IMyInterface {}, but the static modifier had no effect because it makes no sense in this context.

Sometime after Microsoft Dynamics AX 2009 the X++ compiler might stop allowing the static modifier on interface declarations. For more information, see Interfaces Overview.

Modifiers

The static modifier must not be applied to the new constructor

It was possible to apply the static modifier to the declaration of the new constructor method. This caused new MyClass(); to behave as a null operation. Instead, the statement MyClass::new(); would call the static new method, but that would not construct an object.

Now the compiler issues an error when the static modifier is applied to the new method. For more information, see Constructors.

Modifiers

Use an explicit access modifier on each method

In the past the menu item of AOT > Classes > MyClass > New Method created the method without any access modifier. This meant that the method was implicitly public, although some X++ developers might not have been fully aware of the default. This created extra work later when a developer needed to modify the code in the method, because the developer had to research everywhere that the method might be called from.

Now the New Method menu item explicitly includes the private keyword in its automatic declaration of the new method. The developer can type in a different modifier if appropriate. For more information, see Method Modifiers.

Parameters

Parameters given in a call to a new constructor method must match the parameters on the new constructor method

It was possible to pass in multiple parameters on call to a new constructor method even when the new method was declared to input no parameters.

Now the call to the new method must exactly match the declared parameter signature of the new method. For more information, see Creating a Subclass.

Parameters

Parameters with default values must come after all parameters that do not have default values

It was possible to declare a method that takes in two parameters, and have only the first parameter offer a default value. There was no purpose to this. There was no way to accept the default of the first parameter because the call must specify a value for the second parameter and cannot omit the first parameter.

Now in the declaration of a method, any parameter that offers a default value must come after all the parameters that do not. For more information, see the following topics:

Parameters

Override of a method must have the same default parameters as the overridden method

It was possible to declare a method as public void myMethod(int i=22){} and the override as public void myMethod(){}. But if the override method was called as derivedObject(333); an error occurred.

Now the override method must list the same parameter types in the same sequence that they are declared in the overridden method. For more information, see Overriding a Method.

Preprocessor

A TODO in a comment must be the first non-whitespace in the first line of the comment

The X++ preprocessor used to detect the TODO keyword in a multi-line /* ... */ task comment even when the TODO appeared after other text after the first comment line.

Now the X++ preprocessor detects the TODO keyword only if TODO appears on the first line of the comment, and as the first non-whitespace in the comment. For more information, see TODO Comments for X++ Developer Tasks.

See also

X++ Syntax

Announcements: New book: "Inside Microsoft Dynamics AX 2012 R3" now available. Get your copy at the MS Press Store.