In Microsoft Dynamics AX 2012, we made compiler changes to make the X++ language more reliable and to prevent problems that may cause runtime errors.

 1.  Super() cannot Call an Abstract Method

Suppose an abstract method is implemented by a derived class.  If the method in the derived class tries to call super() to reach the abstract method in the base class, the X++ compiler will report an error.  For example:

// X++

class BaseClass
{
    public abstract int method1()
    { }
}

class DerivedClass extends BaseClass
{
    public int method1()
    {
        return super();  // Invalid call.
    }
}

 

 Reason for the Change

Abstract methods have no code body. Therefore any call to an abstract method is meaningless.

 

2.  All Default Parameters are required to follow the Last Non-default

The X++ compiler rejects any method parameter signature which lists a default parameter before the last regular non-default parameter.

In the following X++ method signatures, parameter ‘i’ is a default parameter that causes both methods to fail to compile.

public void myInvalidMethod1(int i=1, int q) { }  // Invalid signature

public void myInvalidMethod2(int i=1, int q, int r=8) { }  // Invalid signature

 

Reason for the Change

It does not make sense to have non-default parameters follow default parameters. In such cases all calls to the method must provide an explicit value for the default parameter, and the parameter could never take its default. Therefore it understandable that .NET CIL does not support such cases. Starting in AX 2012 the X++ compiler no longer supports such cases either, to be compatible with CIL.

 

3.  Methods that Override Should Match the Parent Signature

When a method in a derived class has the same name as a method in its base class, the X++ compiler requires the exact same parameter signature for the two methods. Also, both methods must have the exact same return type. Otherwise the derived class will fail to compile.

For example, in AX 2012 under AOT > Classes, the X++ abstract class SysAttribute is extended by the class SrsReportNameAttribute. Therefore an instance of SrsReportNameAttribute can be passed to a method that takes a parameter of type SysAttribute. But for overriding a method, these two types would not be considered an exact match, and the X++ compiler would not consider these two types to be the exact same kind of parameter or return type.

In the following X++ code example, the MyDerivedClasswould fail to compile: 

// X++

class MyBaseClass
{
    protected void getAttribute(SysAttribute _sysAttrib) { }
}

class MyDerivedClass extends MyBaseClass
{
    protected void getAttribute(SrsReportNameAttribute _srsReportNameAttrib)
   
{   }    //will not compile
}

 Further, no default parameter can exactly match a non-default parameter, or vice verse. The number of parameters must also match. X++ supports method overriding, but not method overloading.

These rules also apply when a class implements an interface.

Reason for the Change

Without this new restriction enforced by the X++ compiler, these incompatibility errors would be detected only during run time. The above X++ code example would compile in AX 2009, but in AX 2012 the X++ compiler will reject this example.

 

4.  Interface Implementation Must be Complete

An X++ class that implements an interface must provide code for all the methods of the interface. This includes any methods the interface inherits from another interface.

In the following X++ code example, BadClass fails to compile in AX 2012:

// X++

interface IF1
{
    void method3();
}

interface IF2 extends IF1
{
    void method4();
}

class BadClass implements IF2   // Fails to compile, is missing method3.
{
    public void method4()
    { }
}

 

Reason for the Change

Same as for item 3 above.

 

5.  The Same Method Name cannot be Inherited from both Base Class and Interface

Suppose a derived class both extends a base class and implements an interface.  And suppose that the base class and the interface specify the same method name. The X++ compiler no longer tolerates this situation.

In the following X++ code example, the SadClass class fails to compile in AX 2012:

// X++

abstract class YourClass
{
    void method5() { }
}

interface YourIF
{
    void method5() { }
}

// SadClass fails to compile, because the name 'method5' is inherited twice.

class SadClass extends YourClass implements YourIF
{
    public void method5()
    {
        info("Hello World.";)
    }
}

 

Reason for the Change

Same as for item 3 above.