Try OpenEdge Now
skip to main content
GUI for .NET Programming
Accessing and Managing .NET Classes from ABL : Supported features and limitations : Limitations of support for .NET classes
 

Limitations of support for .NET classes

In ABL, you can use many features of .NET classes much as you would in a CLS-compliant language. However, ABL does have the following limitations on the classes you can access and the features you can use:
*Accessing .NET classes and class members — From ABL, you can access most .NET classes and class members. However, ABL either does not support certain .NET classes or provides its own syntax to support the features that they provide. The following table lists the specific restrictions on accessing .NET classes and methods and describes any ABL equivalent support. If you attempt to use one of the restricted .NET classes or methods listed in this table, the ABL Virtual Machine (AVM) raises a run-time error.
Restriction
ABL support
You cannot access a .NET type that is defined in the default namespace (with no namespace defined).
ABL can only access .NET types that have a namespace defined for them.
You cannot use an instance of System.Threading.Thread or any class derived from it.
Not supported—the AVM is single threaded.
You cannot use an instance of System.Delegate or any delegate type derived from it. However, when you implement a .NET abstract or interface event in ABL, you must make reference to a delegate type in order to specify the event signature.
A .NET delegate type (delegate) is a special type of class that defines an event handler method for any .NET event that requires it. ABL allows you to associate either a class-based ABL method or an internal procedure as an event handler for a given .NET event. You must reference the documentation for the associated .NET delegate to determine the signature required to define an ABL handler for the event or to publish any .NET abstract or interface event that you implement. For more information, see the .
You cannot call the static method, System.Windows.Forms.Application:DoEvent( ), anywhere.
In a .NET application, the Application:DoEvent( ) method invokes event handlers for all currently published events that have not yet been handled. In ABL, you invoke the PROCESS EVENTS statement to handle currently published events. For more information, see Handling .NETevents.
You cannot call the static method, System.Windows.Forms.Application:Run( ), outside of a WAIT-FOR statement.
In a .NET application, the Application:Run( ) method blocks for non-modal form input. In ABL, you must invoke this method within a WAIT-FOR statement to block for non-modal form input. For more information, see Blockingon non-modal forms.
You cannot call the instance method, System.Windows.Forms.Form:ShowDialog( ), outside of a WAIT-FOR statement.
In a .NET application, the ShowDialog( ) method blocks for input in the modal form instance (dialog box) on which you call it. In ABL, you must invoke this method within a WAIT-FOR statement to block for a dialog box. For more information, see Blockingon modal dialog boxes.
You cannot call a .NET generic method.
You can call non-generic methods on a .NET generic class or interface object. However, .NET generic methods use a separate mechanism that ABL does not support.
*Extending .NET classes — You cannot define an ABL class that inherits from a .NET class that is itself defined with any of the following .NET directives (as specified in C#):
*internal
*private
*sealed
*static
You cannot define an ABL class that inherits from a .NET generic class.
You cannot define an ABL class that can become an additional part for a .NET partial class.
You cannot override the following methods of an inherited .NET class:
*DestroyHandle( )
*Dispose( )
*Finalize( )
*GetHashCode( )
If your non-abstract ABL class inherits from a .NET abstract class, it must implement (override) all abstract properties, methods, and events of the inherited class. However, you cannot inherit from a .NET abstract class that defines an abstract indexed property (including a default indexed property), because ABL has no support for overriding and defining indexed properties. For more information on these restrictions, see Deriving.NET classes in ABL.
An ABL class cannot inherit from the following .NET class types or any class types that are derived from them:
*System.Delegate
*System.Enum
*System.Threading.Thread
*System.ValueType
For more information on these restrictions, see Features of ABL classes that implement .NET interfaces.
*Implementing .NET interfaces — You cannot implement a .NET interface that:
*.NET defines as internal
*.NET defines as generic or that, itself, specifies a generic method
*Defines an indexed property (including a default indexed property)
Also note that ABL has no support for explicit interface members. If you implement more than one .NET interface that defines a property or method with identical signatures, these identical properties or methods must all share the same implementation.
*Blocking for events — If you use any non-modal .NET forms in your application, you can simultaneously execute only one WAIT-FOR statement at a time that invokes a non-modal .NET input-blocking method (such as System.Windows.Forms.Application:Run( )) to process events on all simultaneously open non-modal .NET forms. You can also use this same WAIT-FOR statement to simultaneously process events for non-modal ABL windows and non-GUI features that are active in the ABL session, such as sockets and asynchronous remote procedure calls. For more information, see ABL support for managing .NET forms and controls.
Note: You can use as many WAIT-FOR statements as required, anywhere in your application, to block on modal .NET or ABL dialog boxes.
*.NET objects in non-GUI ABL applications — While you can access .NET objects in non-GUI ABL sessions, you cannot visualize .NET forms and controls in a non-GUI session. You also cannot execute the .NET WAIT-FOR statement or otherwise block for and handle .NET object events in a non-GUI session. The ABL sessions with these limitations include:
*Character-mode clients
*Batch clients
*AppServer agents
*WebSpeed agents
However in these sessions, you can use all other supported features of .NET objects.
*Publishing .NET events — You cannot directly publish (send or fire) .NET object events from ABL. Each .NET object is responsible for publishing its own events, which you can then handle in ABL using event handlers. However, if a .NET object provides protected or public methods for publishing events programmatically on behalf of the object, you can also invoke these methods from ABL to publish the specified events. The use of these .NET methods in ABL is analogous to using the APPLY statement to publish ABL events "to" a specified widget or handle. If you inherit and implement an abstract .NET event in ABL, you can publish the event directly in the implementing ABL class using the ABL Publish( ) event method.
*.NET operator overloading — In CLS-compliant languages, .NET classes support the ability to overload operators of the language, like plus (+), for a given class. This overloading allows a function to be defined and executed for the operator when the operator is used with instances of a given class, such as adding two objects together (Obj1 + Obj2). In ABL, for most .NET classes, you can only access the functionality of .NET overloaded operators using .NET reflection on a class. However, ABL does provide a helper class (Progress.Util.EnumHelper) that has static methods for performing standard operations on enumeration types. For more information on enumeration types, see Accessing and using .NET enumeration types.
Note: ABL does not support operator overloading for user-defined classes.
*Casting .NET data types — As with ABL user-defined types, you can cast references to .NET object types, including .NET generic types, using the ABL built-in CAST function. However, unlike CLS-compliant languages, you cannot include .NET primitive types in this ABL type casting.
*.NET classes and OpenEdge startup options — .NET classes do not adhere to OpenEdge run-time startup parameters or .ini file settings. You must control such options using general Windows settings or in ABL through programmatic control of each .NET object that you create.
*Accessing Progress.Lang.Class on .NET objects — Although all .NET classes in ABL extend Progress.Lang.Object, you cannot access Progress.Lang.Class from a .NET object using the GetClass( ) method inherited from Progress.Lang.Object. On a .NET object, any attempt to call the Getclass( ) method on a .NET object returns the Unknown value (?). To do reflection on a .NET object, use the .NET native reflection mechanism, in particular, the properties and methods of System.Type.
In addition, there are more specific limitations in the syntax and behavior of some of the supported features. This documentation notes these limitations for each feature where they apply.