You can call .NET Framework type members, including methods, properties, and constructors, from C/AL code with the DotNet data type for C/AL variables. This section provides an overview of the DotNet data type, guidelines on its use, and aspects about calling members of a .NET Framework type. For information about how to create and use a DotNet variable to call members of a type, see How to: Call .NET Framework Members from C/AL Code.

DotNet Data Type

The DotNet type resembles the Automation type in C/AL except that it references a .NET Framework type in an assembly. Assemblies can be either part of assemblies that are installed in the global assembly cache or custom assemblies that you have installed for Microsoft Dynamics NAV. For more information about installing assemblies in global assembly cache, see Assembly Installation in the GAC.

After you have defined a DotNet variable, you can call it in C/AL code to instantiate members of a .NET Framework type.


A constructor is a method that creates an instance of an object and prepares it for use. Before you use a DotNet variable, you should verify whether the variable is static or is an object instance because this determines whether you have to use a constructor.

  • Static variables do not require a constructor because they do not have an instance.

  • Object instance variables require a constructor because they must be created before they can be accessed.

To find the constructor and other methods and property for your object, in Object Designer, click Symbol.

Static and Instance Method Calls

Methods that you call from C/AL code can be either static or instance methods.

  • You use the same syntax to call static and instance methods.

  • Calling static methods provides a factory pattern for creating object instances. For example, to create a new System.TimeZoneInfo object, you call the type’s System.TimeZoneInfo.Local static method with the following code:

      Copy Code
    zone := zone.Local;
  • A static class or object is loaded once per Microsoft Dynamics NAV Server instance, and the class or object is shared between all clients that are connected to the server instance. The data that is maintained by the static class or object is visible by all clients that use the type. You should consider this in your .NET Framework interoperability design to help avoid disclosing private information.

C# Indexers

A C# indexer is represented as an Item property in C/AL. For example, in C#, the following code sets an array element N to the value M:

  Copy Code
arrayVariable[N] = M;

In C/AL, the corresponding code is as follows:

  Copy Code
arrayVariable.Item(N) := M;

Indexers can also be overloaded. In Object Designer, click C/AL Symbol Menu to see the parameters and return types for the indexer.

Indexers for lists and arrays that are defined by .NET Framework variables are zero-based, which means that they start at 0. Other indexers in C/AL start at 1.

Operators for Comparing .NET Framework Objects

.NET Framework interoperability does not support direct use of operators to compare two DotNet variables. For example, the following scenario is not supported:

  Copy Code
IF dotnetVar1 <= dotnetVar2 THEN

If you want to compare two DotNet variables, then you can use the Equals function on the DotNet variables as shown in the following example:

  Copy Code
IF dnVersion1.Equals(dnVersion2) THEN …

You can perform comparisons by using .NET Framework methods and properties that return compatible C/AL types because these objects are implicitly converted to C/AL types before the comparison takes place. For example, the following C/AL code includes three DotNet variables for the System.Collections.Generic.List class: dotNetList1, dotNetList2, and dotNetList3. You cannot compare the DotNet variables directly because they do not return C/AL types. You can perform comparisons on the List.Capacity property because the List.Capacity property is a NET Framework integer type that returns a C/AL integer type. For more information about conversion between .NET Framework and C/AL types, see .NET Framework Type Conversion.

  Copy Code
dotNetList1 := dotNetList1.List(5);
dotNetList2 := dotNetList2.List(10);
dotNetList3 := dotNetList3.List(5);
IF dotNetList1.Capacity <> dotNetList3.Capacity THEN
  ERROR('List1 and List3 should have the same capacity.');
IF dotNetList1.Capacity = dotNetList2.Capacity THEN
  ERROR('List1 and List2 should not have the same capacity.');
IF dotNetList1.ToString() <> dotNetList2.ToString() THEN
  ERROR('List1 and List2 should have the same ToString output.');

Events and Public Fields

Microsoft Dynamics NAV 2009 R2 does not support events and public fields in the .NET Framework.

Long Member Names

There is a limit of 30 characters on member names. To call a constructor that is longer than 30 characters, use the C/AL Symbol Menu because the constructor names are automatically truncated to 30 characters. You cannot directly call methods and properties that are more than 30 characters long because you cannot compile the Microsoft Dynamics NAV object. To resolve this issue, you can create a method that wraps the original method or property and has a name that is 30 characters or fewer. From C/AL code, you can then call the new method instead of the original method or property.

Case Sensitivity in Member Names

NET Framework member names in C/AL code are case-sensitive. If you use the incorrect case when you call a member, then you get an error when you compile the object. This behavior differs from other C/AL variables because you can mix cases and still compile the object. For other C/AL variables, the case is corrected automatically the next time that you open the object.

Local DotNet Variable Limitations

You should not assign a local DotNet variable to global C/AL or .NET Framework objects because the local DotNet variable is disposed when it goes out of scope. If you use the DotNet variable outside the scope of its local function, then you should define it as a global DotNet variable.

See Also