microsoft / microsoft/AL

Dictionary.Get(key, var Interface) overload causes CLR CS1503 error: interface argument passed by value instead of ByRef

Open
#8,247 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

accepted al-core-compiler bug
Dominant language
PowerShell
Stars
881
Forks
285
Avg merge
3d 36m
Merged PRs (30d)
1

Description

1. Describe the bug
Using the two-argument Dictionary.Get(Key, var Value) overload where the value type is an Interface causes a CLR CS1503 compilation error at runtime. The AL compiler accepts the code without warnings, but the server-side C# compilation fails because the interface handle is passed by value instead of ByRef.

2. To Reproduce

  1. Declare a global Dictionary of [Text, Interface "IMyInterface"]
  2. Call the two-argument Get overload, passing a var Interface parameter as the output argument
codeunit 50000 "My Codeunit"
{
    var
        MyDict: Dictionary of [Text, Interface "IMyInterface"];

    local procedure TryGet(Key: Text[30]; var Result: Interface "IMyInterface"): Boolean
    begin
        exit(MyDict.Get(Key, Result)); // Triggers CLR CS1503 at runtime
    end;
}

3. Expected behavior
Dictionary.Get(Key, var Value) should work for Interface value types, the same way it works for scalar types (Text, Integer, etc.), returning true/false and assigning the found value to the output parameter.

4. Actual behavior
The AL compiler reports no error, but at runtime the server-side C# compilation fails with:

System.InvalidOperationException: C# compilation has failed for the application object CodeUnit_XXXXXXX.
error CS1503: Argument 3: cannot convert from 'Microsoft.Dynamics.Nav.Runtime.NavInterfaceHandle'
to 'Microsoft.Dynamics.Nav.Runtime.ByRef<Microsoft.Dynamics.Nav.Runtime.NavInterfaceHandle>'

The workaround is to split the call into ContainsKey + single-argument Get:

local procedure TryGet(Key: Text[30]; var Result: Interface "IMyInterface"): Boolean
begin
    if MyDict.ContainsKey(Key) then begin
        Result := MyDict.Get(Key);
        exit(true);
    end;
end;

5. Versions:

  • AL Language: 17.0
  • Visual Studio Code: 1.117
  • Business Central: 28
  • Operating System:
    • Windows

Internal work item: AB#634057

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the two-argument Dictionary.Get(Key, var Value) overload for Interface value types and compare its generated server-side C# call with scalar types. Reproduce the supplied TryGet example; done means the call compiles at runtime and returns the expected Boolean result while assigning the interface output without the ContainsKey workaround.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
compilers, devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.