Try OpenEdge Now
skip to main content
GUI for .NET Programming
Using .NET data types in ABL : Accessing and using .NET arrays : Accessing .NET arrays
 

Accessing .NET arrays

The first thing to note about accessing .NET arrays is that, by default, .NET array dimensions use zero (0)-based indexing as compared to ABL arrays, which always use one (1)-based indexing.
Caution: This means that when working together with ABL and .NET arrays, ABL arrays are always indexed from 1 to the array size while .NET array dimensions are typically indexed from 0 to the dimension size minus 1.
Note: .NET allows you to specify the base index value for dimensions of any .NET array that you create. However, in practice, almost all .NET arrays are created to use the zero-based index default.
You can access a .NET array created in the .NET context, like any other .NET object, by using its object reference directly from a .NET class member, or by defining an ABL object reference variable or property and assigning the .NET class member to it.
You can also instantiate a .NET array object in ABL, but not by using the NEW function or statement, as for other .NET objects. Recall that the base .NET class for all array objects is System.Array. This class also provides the mechanism you must use to create and manage instances of all .NET array classes. In other words, System.Array is both the base class and the factory for creating and managing .NET arrays of all types. When you use System.Array to create a .NET array instance, it creates an instance of the specified .NET array type, even if you assign the object reference that you create to a data element of type System.Array. You can continue to use the System.Array data element to access elements of the created array type. You can also cast the System.Array instance as necessary to make it type compatible with a method parameter or property assignment.
Thus, the System.Array class provides a variety of public static and instance members that you can use to create and manage .NET array objects. The basic System.Array members for working with array objects include the:
*CreateInstance( ) static (factory) method — Creates and returns an instance of System.Array for a given element type. This method is overloaded to create arrays from one to any number of dimensions. The first parameter of this method is a System.Type that describes the object type of each element in the array contents. You can provide this element type as the value returned by one of the following GetType( ) methods:
*OpenEdge static Progress.Util.TypeHelper:GetType( ) method
*Microsoft .NET static System.Type:GetType( ) method, as long as the type resides in the .NET core assembly (mscorlib.dll)
*.NET GetType( ) method on an instance of the class that the array contains
All three GetType( ) methods return an appropriate System.Type object that corresponds to a given object type name specified as a string:

Syntax

System.Array System.Array:CreateInstance
  (class-type-or-instance:GetType( [type-name-string] ), dimensions)
The class-type-or-instance can be one of the following, depending on how you obtain the element type:
*Progress.Util.TypeHelper
*System.Type
*An object reference to an instance of the class that can be stored as an element of the array
Note that you specify the type name (type-name-string) using a fully qualified type name and only when using the GetType( ) static method on Progress.Util.TypeHelper or System.Type. The instance GetType( ) method takes no parameters. The dimensions represents one or more parameters that define the dimensions of the array.
Note: If you call the GetType( ) method on Progress.Util.TypeHelper in order to reference a type that does not reside in the .NET core assembly, you must include the assembly where the type resides in your working assembly references file (assemblies.xml). For more information on assembly references files, see Identifying .NET assemblies to ABL.
When CreateInstance( ) creates the specified array, it initializes the array elements, depending on the type. For reference types, it initializes each element to a null reference. For value types, it initializes each element to its default or 0 value.
*SetValue( ) instance method — Stores an object reference at the specified location in the array, overloaded depending on the number of dimensions:
VOID array-object-ref:SetValue( element, index-info )
The array-object-ref is a reference to an array object instance. The element is an ABL primitive value or a reference to an object you want to store as an element of the array. The index-info represents one or more parameters that identify the element location, depending on the array dimensions.
Note: The element parameter is defined as System.Object. So, if element is an ABL primitive type, and you want to store a .NET mapped data type other than the default match for that ABL data type, you must specify the AS option with the AS data type that matches the explicit .NET mapped type (see Passing ABL data types to .NET constructor and method parameters).
*GetValue( ) instance method — Returns an object reference to the element type from the specified location in the array, overloaded depending on the number of dimensions and extents:
System.Object array-object-ref:GetValue( index-info )
The array-object-ref is a reference to an array object instance. The index-info represents one or more parameters that identify the element location, depending on the defined dimensions of the array and their extents. Typically, you want to cast the return value to the type of object that the array stores.
*Item default indexed property — This property, defined as System.Object, provides indexed read and write access to each element of an array object, similar to how you use a subscript to access an ABL array. Item is actually an explicit interface member of the System.Collections.IList interface, which System.Array implements. If you cast an array object to this interface type, you can then read or write all of the array elements using the default property indexer directly on the IList object reference, as in the following example:
USING Progress.Util.* FROM ASSEMBLY.

DEFINE VARIABLE strArr AS CLASS System.Collections.IList NO-UNDO.

strArr    = CAST(System.Array:CreateInstance
                  (TypeHelper:GetType("System.String"), 2),
                 System.Collections.IList)

strArr[1] = "Spinach".
MESSAGE strArr[1] VIEW-AS ALERT-BOX.
This code fragment defines strArr as an object reference to the IList interface, and it casts a new string array object reference to this interface before assigning that object reference to strArr. It then assigns a string, "Spinach", to the second element of the array (strArr[1], again, zero-based) and reads the same element to display the string in a message. For more information on default indexed properties, see Accessing .NET indexed properties and collections, and for more information on explicit interface members, see Accessing members of .NET interfaces.
For more .NET information on these methods and other members of System.Array, see the Class Library documentation of the Microsoft .NET Framework SDK. For an on-line reference, see OpenEdge Installed .NET Controls.
For a working example of accessing a .NET array using System.Array mechanisms, see Example: Accessing a .NET array.
Note: When you return an ABL object reference from a specified .NET array element, the relationship of that object reference to the object stored in the array element depends on whether the element stores a value type object or a reference type object. If it is a value type object, the ABL object reference points to a separate copy of the object stored by the array element. If it is a reference type object, the ABL object reference points to the same copy of the object stored by the array element. Thus, you must manage and update members of the object stored by the array element differently, depending on the object type. For more information, see Support for .NET object types.