Getting .NET data member, property, and method return values
When returning an OUTPUT parameter from a .NET constructor or method, ABL always has a destination variable in which to store the value. Therefore at compile time, ABL ensures that the .NET parameter and ABL variable are type-compatible according to the OUTPUT parameter mapping tables (see Passing ABL data types to .NET constructor and method parameters). At run time, ABL then converts the .NET output data to the ABL data type of the variable.
However, ABL gets .NET data member (field), property, and method return values differently than for OUTPUT parameters, because they can appear in an expression with no specified return variable. In these cases, ABL always converts the .NET output data to the data type specified in the implicit mapping table (see Table 10).
The following example gets a .NET data member value:
DEFINE VARIABLE iResult AS INTEGER NO-UNDO.
iResult = System.Math:PI.
In this case, ABL converts the .NET System.Double value of System.Math:PI according to the implicit mapping to an ABL DECIMAL with the value 3.1415926535. It then attempts to assign this value to the INTEGER, iResult, which ABL allows, performing the conversion with rounding and assigning a value of 3. If iResult, instead, was attempting to receive the same value passed in an OUTPUT parameter of a .NET method, ABL would raise a compile-time type compatibility error.
The same conversion occurs when getting the method return value in the following example:
DEFINE VARIABLE iResult AS INTEGER NO-UNDO.
iResult = System.Math:Abs(-(System.Math:PI) AS DOUBLE).
Again, the following example is a similar case, where you "assign" the results of the same .NET data member and method return values passed to ABL INPUT parameters. So, this displays "piResult1 = 3 and piResult2 = 3":
PROCEDURE viewResults:
DEFINE INPUT PARAMETER piResult1 AS INTEGER NO-UNDO.
DEFINE INPUT PARAMETER piResult2 AS INTEGER NO-UNDO.
RUN viewResults
(System.Math:PI, System.Math:Abs(-(System.Math:PI) AS DOUBLE)).
Because ABL performs conversion for .NET data member, property, and method return values according to the implicit data type mappings before evaluating these return values in expressions and assignments, data precision and values can be lost consistent with the implicit data type mapping rules. For more information, see Implicitdata type mappings.
If you assign a .NET property or method return value to another .NET property or data member in ABL, you have the same potential for loss of data precision or values because ABL performs the appropriate ABL data conversion before assigning the original .NET value on the right-hand side to the .NET data item on the left-hand side of the assignment. For example, this code fragment assigns the static MaxValue data member of the System.Single class to the System.Single X property of a System.Drawing.PointF object:
DEFINE VARIABLE rPointF AS CLASS System.Drawing.PointF NO-UNDO.
ASSIGN
rPointF = NEW System.Drawing.PointF( 1.0, 2.0)
rPointF:X = System.Single:MaxValue.
ABL evaluates the .NET data member, MaxValue, as an ABL DECIMAL before assigning it to the .NET X property.
If you assign a .NET property, data member, or method return value defined as a System.Object to an ABL data element defined as a primitive type, the assigned System.Object value must be a .NET mapped object type. If the value is a .NET mapped object type, ABL unboxes it from the System.Object and converts it to its matching ABL primitive type before attempting to assign the value to the target ABL data element. For more information on unboxing, see .NET boxingsupport.