Reference .NET generic types
- Last Updated: October 20, 2022
- 4 minute read
- OpenEdge
- Version 13.0
- Documentation
.NET supports a concept of generic (or parameterized) types. A .NET generic type is any .NET class or interface type that uses placeholders for data type names in order to define one or more members or local variables as part of the generic class or interface definition. You determine the actual data types (primitive or object types) for these placeholders by how you reference the generic type name of the class or interface, which includes these placeholders as type parameters. Wherever you reference the generic type name, you substitute each type parameter in the name with an actual data type name. Thus, one generic class actually has multiple implementations based on the possible sets of substitution data types that you can provide for the type parameters in the generic class name. ABL supports references to .NET generic type names using this syntax:
Syntax
|
The namespace is any required .NET namespace. The remaining construction specifies
the .NET class or interface name for the generic type, where object-name is some identifier and Tparm is
a type parameter, of which there can be more than one. The number of type parameters and the
data types you can specify for each one depend on the generic type definition, which can
include constraints for each type parameter. Note that ABL requires surrounding quotes
("") for inner classes (due to the + sign) or .NET arrays (due to [
]). Note also that any number of spaces between type parameters, commas, and
angle brackets are allowed but optional.
When you reference the generic type name for a given implementation of the
type, you replace each defined Tparm in the name with an
appropriate data type for the chosen implementation. This data type must explicitly identify
the .NET type that the generic type requires for a given type parameter. Some .NET data
types, which represent the primitive data types of any .NET language, map directly to ABL
primitive data types, and are therefore referred to as .NET mapped
data types. For example, a .NET System.Int32 maps
to an ABL INTEGER. For these .NET mapped types, you must
specify an ABL data type to identify the corresponding .NET data type. For information on
how ABL primitive types map to .NET types, see Implicit data type mappings.
Note that some ABL primitive types correspond to more than one .NET mapped
type. To specify a particular .NET mapped type, ABL provides extended type keywords called
AS data types that identify a particular .NET mapped type.
For example, to identify a .NET System.Int16, which
implicitly maps to an ABL INTEGER, you must substitute the
SHORT AS data type for the corresponding TParm in a generic type name. For more information on making
explicit references to .NET mapped types, see Explicit data type mappings.
For references to .NET types other than .NET mapped types (all other object
types), you can directly substitute the .NET object type name (for example, System.Drawing.Point or System.Windows.Forms.Button) for the corresponding TParm. You can even substitute another .NET generic type for a TParm, if the specified generic type supports it.
For example, .NET supports a generic stack object that you can use to
create a stack of any .NET type. If you want to define an object reference to a .NET stack
of System.Int16 objects, you can code the following ABL
statement:
|
If you want to define an object reference to a .NET sorted list of
key/value pairs (sorted by the key) consisting of System.String keys and System.Int16 values, you
can code the following ABL statement:
|
Again, the class type names for these .NET
generic types in ABL are System.Collections.Generic.Stack<SHORT> and System.Collections.Generic.SortedList<CHARACTER, SHORT> (respectively).
Reference to them in ABL must be surrounded in quotes only if they are for inner classes or
.NET arrays, to allow the + sign and [], respectively in the name. Like any type name, you can also
make unqualified references to them with an appropriate USING statement, for example,
SortedList<CHARACTER, SHORT>. Note that you can
also use abbreviated ABL type names to specify the Tparm
substitution types in the generic type name, for example, SortedList<CHAR, SHORT>.
Referencing a generic type like this is referred to as constructing the type. Therefore, a reference to a .NET generic type that specifies a particular set of data types for its type parameters is referred to as a reference to its constructed type name. The .NET documentation specifies the type parameters for a given generic type using a generic type definition, which .NET also refers to as an open generic type, or simply an open type. The open type name for a generic type indicates the number and order of its type parameters. The complete definition for an open type also indicates possible substitute data types (constraints) for its type parameters and other information, such as any interfaces that a generic class type implements.
- Inherit from a .NET generic class
- Implement a .NET interface
That is, you cannot specify a .NET generic type for the INHERIT or the IMPLEMENTS
options of the ABL CLASS statement. For more information
on inheriting .NET classes and implementing .NET interfaces, see Extend .NET Objects.
You can also define both .NET and ABL arrays of generic types, and .NET generic types can take .NET array objects as constructed type parameters. For example:
|
In .NET, the System.Collections.Generic
namespace defines many of the generic types in the framework. However, generic types are
also defined in several other .NET object namespaces.
For more information on referencing and working with .NET generic types in ABL, including how to identify the available data types you can substitute for generic type parameters from open types listed in .NET documentation, see Work with .NET generic types.