Try OpenEdge Now
skip to main content
GUI for .NET Programming
Using .NET data types in ABL : General ABL support for .NET types : Support for .NET value types as objects

Support for .NET value types as objects

Many .NET value types map directly to ABL primitive types with no object instance used to represent them (for example, System.Int32 and System.Boolean). You work directly with these .NET types using their ABL data type equivalents (in this case, INTEGER and LOGICAL, respectively). However, .NET has some value types that ABL treats as objects (for example, all structures, such as System.Drawing.Size, and all enumerations). .NET always passes or assigns these value type objects by value. So, you must work with these value type objects differently from reference type objects.
Note: .NET does not allow inheritance from value type objects. Therefore, you cannot define an ABL class that inherits from any .NET value type object (structure or enumeration).
Thus, when .NET passes or returns a value type object to ABL, again, it is passed by value. However within ABL, you refer to the object by reference like any other class-based object. However, any particular instance of a .NET value type object that ABL references is always a new copy of the original instance passed or returned by .NET. This means that the object reference in ABL does not point to the same copy of the value type instance that .NET has. For example:
USING System.Windows.Forms.* FROM ASSEMBLY.

DEFINE VARIABLE rSize1      AS CLASS System.Drawing.Size NO-UNDO.
DEFINE VARIABLE rSize2      AS CLASS System.Drawing.Size NO-UNDO.
DEFINE VARIABLE myObjectRef AS CLASS Button              NO-UNDO.

  myObjectRef = NEW Button( )
  rSize1      = myObjectRef:Size
  rSize2      = myObjectRef:Size

This example assigns the object reference value of the Size property on myObjectRef to two different object reference variables (rSize1 and rSize2). If System.Drawing.Size were a reference type, both of these variables would point to the same object instance. But since this is a value type object, each access to the Size property returns its value, and ABL creates a new instance for the object in the session. In contrast, when .NET returns a reference type object to ABL, no matter how many times it returns the same object, all ABL object references point to that same reference type instance.
As a result, .NET value type objects have some different usage requirements from reference type objects in ABL, as follows:
*Each time you send or receive a value type object between ABL and .NET, you cause a new instance to be created. Depending on the frequency of these assignments and the content of the value type, this can impact performance. Do as much work on the ABL side as possible before assigning a value type back to .NET. Note once you have a given .NET value type in the ABL context, you can assign affected ABL object reference variables to each other with minimal impact because they all reference the same instance.
*You cannot use value type objects in chained references. For example:
  myObjectRef:Size:Width  = 80
  myObjectRef:Size:Height = 40.
This code does not set the Width and Height properties on the System.Drawing.Size object referenced by the myObjectRef:Size property. Instead, it sets the Width and Height properties on a copied instance of System.Drawing.Size that is created when the property is referenced. This is not what is intended. Therefore, the compiler generates an error or a warning on the code construct. If the value type in the middle of the chain is returned from a property or method reference, (i.e. if Size is property), the compiler generates an error. If the value type is obtained from a field reference the compiler generates a warning. In order to modify the properties (or data members) of a value type, you must reset the value type itself to a new instance. For example:
myObjectRef:Size = NEW System.Drawing.Size(80, 40).
For an example of managing .NET value type object references in ABL, see the PointArray.p procedure in the v