Business Central 2024 wave 2 (BC25): Type testing and casting operators for interfaces (‘is’ operator and ‘as’ operator)

Dynamics 365 Business Central

Hi, Readers.
The public preview for Dynamics 365 Business Central 2024 release wave 2 (BC25) is available. Learn more: Link.

I will continue to test and share some new features that I hope will be helpful.

Type testing and casting operators for interfaces:

Business value:
The contractual behavior of interfaces has been a limiting factor with regards to update and future extensibility. Adding casting will greatly increase the usefulness of interfaces in AL. In this version, we introduce support for type testing and casting interfaces in the AL language. Two new operators, ‘is’ and ‘as’, have been added to facilitate these operations. The ‘is’ keyword checks if an interface is of a specific type, which is useful for ensuring type safety within code. The ‘as’ keyword, on the other hand, attempts to cast an interface to another interface. These operators improve the extensibility and usefulness of interfaces in AL and align with the broader programming practice of ensuring that systems are built with future growth and adaptability in mind, allowing for seamless updates and maintenance.

https://learn.microsoft.com/en-us/dynamics365/release-plan/2024wave2/smb/dynamics365-business-central/type-testing-casting-operators-interfaces?wt.mc_id=DX-MVP-5004336

In the previous post, we discussed Business Central 2024 wave 2 (BC25): Extend AL interfaces. The following is a brief introduction to AL interfaces. If you have read the previous post, you can skip it.

An interface in AL is similar to an interface in any other programming language; it’s a syntactical contract that can be implemented by a nonabstract method. The interface is used to define which capabilities must be available for an object, while allowing actual implementations to differ, as long as they comply with the defined interface. More details: Interfaces in AL
This was a new object type in Business Central 2020 Wave1 (BC16).

The interface declares an interface name along with its methods, and codeunits that implement the interface methods, must use the implements keyword along with one or more interface names. The interface itself doesn’t contain any code, only signatures, and can’t itself be called from code, but must be implemented by other objects. Let’s look at a simple example.

1. Create a new interface object: Procedure with declaration only

2. Create a codeunit that implements this interface: declare the code of the procedure

The name and number of the procedure, whether it has a return value, and the type of the return value must be the same as defined in the interface object. Otherwise an error message will be displayed.

‘ImplementZYTest’ does not implement the interface member ‘ZYTestInterface.ShowMessage’. AL AL0582

And

‘PrivateAddressProvider’ does not implement the interface member ‘IAddressProvider.GetAddress2’. AL AL0582

3. Use the new Interface object:

Please note that if you do not specify which codeunit to read before calling the interface, the following error will be prompted.

Interface not initialized

There are two more special initialization ways:
1. Pass codeunit directly as a variable to the function

2. By Enum object: This is useful for situations where there are multiple procedures

Test code:

interface ZYTestInterface
{
    procedure ShowMessage()
}

codeunit 50102 ImplementZYTest implements ZYTestInterface
{
    procedure ShowMessage()
    begin
        Message('Hello World');
    end;
}

pageextension 50100 CustomerListExt extends "Customer List"
{
    trigger OnOpenPage()
    var
        ZYTestInterface: Interface ZYTestInterface;
        ImplementZYTest: Codeunit ImplementZYTest;
    begin
        ZYTestInterface := ImplementZYTest;
        ZYTestInterface.ShowMessage();
    end;
}

Let’s look at a more complex example. (I modified the Microsoft example a bit)
The first is the definition of interface and codeunit. This time there are two codeunits implemented to the same interface.

The same interface is executed in two different actions, but the initialization codeunit is different.

Great.

PS: Interface example from Microsoft Learn

In this version (BC25), Microsoft introduces support for casting between AL interfaces. Given an interface A, you can cast it to the interface B if the underlying object (only codeunit for now) implements B. Two new operators, ‘is’ and ‘as’, are added to facilitate these operations.

The is operator: The is operator allows you to test whether an instance of an interface, or the content of a variant supports a specific interface. Here’s the syntax for using the is keyword:

procedure TestInterface(intf: Interface IFoo)
begin
    if intf is IBar then
        Message('I also support IBar');
end;

For example,

PS: You can also use the is operator with variants:

procedure TestVariant(v: Variant)
begin
    if v is IBar then
        Message('I support IBar');
end;

The as operator: The as operator is used for casting an instance of an interface to a specific interface.

procedure CastInterface(intf: Interface IFoo): Interface IBar
begin
    exit(intf as IBar); // Throws an error if 'intf' doesn't implement 'IBar'
end;

If the source interface doesn’t implement the target interface, it will throw an error at runtime. Here’s an example:

The expression cannot be the target interface.

For example,

PS: Similarly, the as keyword works with variants:

procedure CastInterface(v: Variant): Interface IBar
begin
    exit(v as IBar); // Throws an error if 'v' doesn't implement 'IBar'
end;

Great, give it a try!!!😁

PS:
1. Business Central 2024 wave 2 (BC25): Use the ternary operator ?: when coding in the AL language

2. Business Central 2024 wave 2 (BC25): Use the ‘this’ keyword for codeunit self reference

END

Hope this will help.

Thanks for reading.

ZHU

コメント

Copied title and URL