Like ABL interfaces, .NET interfaces can define properties, methods, and events. Similar to an ABL interface type, an object reference defined as a .NET interface type allows you to access members of any .NET class instance that implements the interface, including all public properties, methods, and events defined by the interface. Thus, .NET interfaces support access to classes that implement them in the same manner as ABL interfaces.

You can also define an ABL class that implements the properties, methods, and events of a .NET interface in much the same way as it might implement an ABL interface. For more information, see Extend .NET Objects.

How to handle explicitly implemented methods

Unlike ABL classes, .NET classes can implement interface members in a special manner that allows you to access that member only using an object reference defined as the interface type. .NET provides this feature to handle the implementation of multiple interfaces that define identical members, each of which is intended to be implemented for a different application. Thus, if the same .NET class implements more than one such interface, it can implement that identical member differently for each interface.

To enable you to tell the class which member implementation you want to access, .NET allows you to identify the member explicitly using an object reference defined with the associated interface type. .NET also requires the class to implement and identify that interface member as an explicit interface member, which you can only access using the interface type. If you try instead to access an explicit interface member using an object reference to its implementing class type, .NET raises an exception, even if the class implements the member for only one interface.

If you want to know if a method is explicitly implemented, refer to the vendor's documentation. If you want to know more about .NET explicit interfaces, see "Explicit Interface Implementation (C# Programming Guide)" in the .NET documentation.

For example, you might have a Vehicle class that implements a Drive( ) method that is defined with an identical signature by a Car interface and a Train interface, both of which are implemented by the Vehicle class. However, the Vehicle class must implement the Drive( ) method differently for a car than it does for a train, and a user of the Vehicle class must be able to access the implementation of the Drive( ) method that is appropriate for their particular vehicle, whether it be a car or a train.

The following code fragment creates a three-element .NET array (System.Array class) of System.Int32 elements, which ABL maps as INTEGER. It then defines object references for two interface types that System.Array implements and sets them to reference the array instance that is created using the NEW statement:

DEFINE VARIABLE rArray AS System.Array NO-UNDO.
DEFINE VARIABLE rIList AS System.Collections.IList NO-UNDO.
DEFINE VARIABLE rICollection AS System.Collections.ICollection NO-UNDO.
ASSIGN
  rArray = NEW "System.Int32[]"(3)
  rIList = rArray
  rICollection = rArray.

rArray:SetValue(0, 0).
rArray:SetValue(1, 1).
rArray:SetValue(2, 2).

MESSAGE "Array element 1 = " rIList[1] VIEW-AS ALERT-BOX INFORMATION.
MESSAGE "Array Count = " rICollection:Count VIEW-AS ALERT-BOX INFORMATION.

rIList:Clear( ).

MESSAGE "Cleared array element 1 = " rIList[1] VIEW-AS ALERT-BOX INFORMATION.
Note: For information on creating and using .NET arrays, see Access and use .NET arrays.

Finally, it initializes the array with the INTEGER values 0, 1, and 2 in their respective array elements, then accesses two explicit interface properties (the default indexed property and the Count property) and one explicit interface method (the Clear( ) method) on their respective interface references.

In this case, MESSAGE statements display the initialized value at position 1, the count of the elements, and the cleared value at position 1 in the array.

Note: You can do all of these array operations using public properties and methods of System.Array. However, this code uses explicit interface methods and properties for demonstration.

On the other hand, if you attempt to invoke these explicit interface methods and properties on a reference to the System.Array class instance, ABL raises compile-time errors (see the bold code in the example below). The errors occur because System.Array does not implement an interface that contains an indexed or Count property or a Clear() method, such as IList.

DEFINE VARIABLE rArray AS System.Array NO-UNDO.
rArray = NEW "System.Int32[]"(3).

rArray:SetValue(0, 0).
rArray:SetValue(1, 1).
rArray:SetValue(2, 2).

/* All of the following bolded code results in compile-time errors */
MESSAGE "Array element 1 = " rArray[1] VIEW-AS ALERT-BOX.
MESSAGE "Array Count = " rArray:Count VIEW-AS ALERT-BOX.

rArray:Clear( ).

MESSAGE "Cleared array element 1 = " rArray[1]
  VIEW-AS ALERT-BOX INFORMATION.