Add foundational AL developer knowledge

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Jesper Schulz-Wedde 2026-09-18 15:42:44 +02:00
parent 38ad6b8810
commit bcc01b3996
23 changed files with 483 additions and 4 deletions

View file

@ -0,0 +1,20 @@
interface "I Quote Amount Bad"
{
procedure GetAmount(): Decimal;
}
interface "I Quote Date Bad"
{
procedure GetDate(): Date;
}
codeunit 50611 "Quote Reader Bad"
{
procedure GetDate(Quote: Interface "I Quote Amount Bad"): Date
var
DatedQuote: Interface "I Quote Date Bad";
begin
DatedQuote := Quote as "I Quote Date Bad";
exit(DatedQuote.GetDate());
end;
}

View file

@ -0,0 +1,24 @@
interface "I Quote Amount Good"
{
procedure GetAmount(): Decimal;
}
interface "I Quote Date Good"
{
procedure GetDate(): Date;
}
codeunit 50610 "Quote Reader Good"
{
procedure TryGetDate(Quote: Interface "I Quote Amount Good"; var QuoteDate: Date): Boolean
var
DatedQuote: Interface "I Quote Date Good";
begin
if not (Quote is "I Quote Date Good") then
exit(false);
DatedQuote := Quote as "I Quote Date Good";
QuoteDate := DatedQuote.GetDate();
exit(true);
end;
}

View file

@ -0,0 +1,30 @@
---
bc-version: [25..]
domain: interfaces
keywords: [interface, is-operator, as-operator, type-test, cast, variant, runtime-error]
technologies: [al]
countries: [w1]
application-area: [all]
---
# Guard optional interface casts with `is`
## Description
From runtime 15.0, AL can type-test an interface or `Variant` with `is` and cast it to another interface with `as`. The test is non-throwing, but `as` raises a runtime error when the underlying codeunit does not implement the target interface. This matters when an extended capability is optional or implementations can come from other extensions.
## Best Practice
Use `is` to establish that the value supports the target interface before using `as`. Cast directly only where the target implementation is an invariant guaranteed by the surrounding contract.
See sample: [`guard-interface-casts-with-is.good.al`](guard-interface-casts-with-is.good.al).
## Anti Pattern
Using `as` unconditionally for an optional extended interface. An otherwise valid implementation of the base interface then fails at runtime merely because it does not implement the additional contract.
See sample: [`guard-interface-casts-with-is.bad.al`](guard-interface-casts-with-is.bad.al).
## Reference
[Understand type testing and casting operators for interfaces](https://learn.microsoft.com/en-us/training/modules/business-central-interfaces/type-testing)