Specifies the name of an ABL or .NET data type that you can specify as a single instance or
as an array of such instances. Thus, an ABL data type can be a built-in primitive type or an
array of such primitive types, or it can be a class-based built-in or user-defined object
type (such as a class, enumeration, or interface type) or an ABL array of such object types.
A .NET data type can only be a class-based object type (such as a class, structure,
enumeration, or interface) or an ABL array of such object types. The EXTENT option, used to
define an array of types, is thus counted as part of the array type name.
Syntax
{ primitive-type-name | object-type-name } [ EXTENT [ constant ] ]
|
-
primitive-type-name
-
An unquoted string that specifies the name of a built-in
ABL primitive type. For information on the supported primitive types
and their names, see the Data types reference entry.
-
object-type-name
-
Specifies an ABL or .NET object type using the following syntax:
[ " ] ABL-object-type [ " ] |
[ " ] dotNET-object-type [ " ]
|
- [ " ]
ABL-object-type
[ " ]
- An ABL object type, where ABL-object-type consists
of text elements with the following syntax:
[ package-name . ] class-interface-or-enum-name
|
-
package-name
- A period-separated list of text components that, along with
class-interface-or-enum-name, uniquely identify an ABL class,
interface, or enum. These text components specify a package that is based on a valid
directory pathname, relative to PROPATH, which identifies the location of the file that
defines the class, interface, or enum. Thus, each text component of
package-name maps to a directory level in the path, and each slash
separator in the path corresponds to a period separating two components.
If specified,
the relative path of the class definition file represented by
package-name must remain constant between compile time and run
time. If the class definition file resides directly on PROPATH, the class or interface
is not defined in a package and therefore has no package-name in
its type name.
With the presence of an appropriate USING statement you can also specify an ABL object
type that is defined in a package using the
class-interface-or-enum-name without its qualifying
package-name. For more information, see the notes for this
reference entry.
-
class-interface-or-enum-name
-
The name of an ABL class, interface, or enumeration. This name must match the name of
a class definition file (excluding the .cls or .r
extension) located in the relative path represented by
package-name, if specified. The name must begin with an alphabetic
character and it cannot contain a period or a space.
If the ABL-object-type has a package-name that
contains embedded spaces, you must enclose the entire
ABL-object-type in quotes ("). Otherwise, quotes
are optional.
Note: Do not place a class definition file in a directory whose name
contains a period (.) character; ABL interprets the component after
the period as another directory level and will therefore not find the referenced class
definition file.
- [ " ]
dotNET-object-type
[ " ]
- A .NET object type, where dotNET-object-type consists
of text elements with the following syntax:
[ namespace . ] dotNET-object-name [ + inner-name ]
|
-
namespace
-
A period-separated list of text components that, along with dotNET-object-name,
uniquely identify a .NET type. The components of namespace are
defined according to .NET requirements. ABL does not support
access to .NET types defined in the default namespace. In
other words, you cannot access a .NET type that does not have
a namespace defined for it.
However, with
the presence of an appropriate USING statement,
you can also specify a .NET object type using the dotNET-object-name without
its qualifying namespace. For more information,
see the notes for this reference entry.
- dotNET-object-name
- The name of a .NET class (including a structure or enumeration), delegate,
interface, or other object type referenced within the .NET namespace
specified by namespace.
- inner-name
- The name of a .NET nested (inner) type defined within
the .NET type definition specified by namespace.dotNET-object-name.
Thus, inner-name can represent the name of an:
Inner class defined by the specified .NET class
Inner enumeration defined by the specified .NET class
Inner interface defined by the specified .NET interface
Caution:
.NET languages normally separate the
name of an inner type from the defining type name using a period
(.). You must replace this period with a plus sign (+) to reference
the inner type name in ABL.
If the name part of the dotNET-object-type contains
any embedded spaces, square brackets ([]), or angle
brackets (<>) you must enclose the entire dotNET-object-type in
quotes ("). Otherwise, quotes are optional.
For
more information on defining object types in ABL, see the CLASS statement or
the INTERFACE statement reference
entry, depending on the type of class-based object.
- EXTENT [
constant ]
-
EXTENT indicates that it is an array of the specified type
and constant is an integer value that specifies
the number of elements in the array. Without constant,
the array is an indeterminate array type.
For more information
on defining ABL data elements with primitive or object types, see
the DEFINE PARAMETER statement, the DEFINE PROPERTY statement, the DEFINE TEMP-TABLE statement, the DEFINE VARIABLE statement, the DEFINE WORK-TABLE statement, or the Parameter definition syntax reference entry.
Example
If
your PROPATH is "C:/myfiles", and your class definition
file name is "C:/myfiles/acme/myObjs/CustObjs.cls", then
ABL requires package-name to be "acme.myObjs." and class-or-interface-name to
be "CustObjs".
The .NET Button class
is in the System.Windows.Forms namespace. Therefore,
you reference its qualified (complete) type name like this:
System.Windows.Forms.Button
|
The .NET ControlCollection class
is an inner class of System.Windows.Forms.Control.
Therefore, you reference its qualified type name like this:
System.Windows.Forms.Control+ControlCollection
|
The following code fragment defines object references
to the .NET type, System.Drawing.Point, and
to a one-dimensional .NET array of System.Drawing.Point elements:
DEFINE VARIABLE rPoint AS CLASS System.Drawing.Point NO-UNDO.
DEFINE VARIABLE rPointArray AS CLASS "System.Drawing.Point[]" NO-UNDO.
|
Notes
- Both elements of an ABL object type name (package-name and
class-interface-or-enum-name) must conform to the case sensitivity
requirements of the operating system (e.g., UNIX or Windows). On a case-sensitive OS, only
the first reference to the object type name must be case correct. ABL follows this initial
letter case for all subsequent references to the type.
- You cannot specify Progress as the first component
of package-name for any ABL user-defined class.
For example, Progress.Inventory.UpdateInv is an invalid
type name for a user-defined class and results in a compiler error.
- You must use a class type name (static type-name syntax)
to qualify all references to the following static members of an
ABL class:
- All PUBLIC static members that you reference from outside
the defining class context.
- All PUBLIC, PROTECTED, or PRIVATE static methods, properties,
events or variable data members that you reference from inside the
defining class context whose names are identical to a reserved keyword.
- PUBLIC or PROTECTED static methods that are overridden in the
current class definition in order to call the specific method definition
in a super class. If you do not use static type-name syntax to call
an overridden static method, the method definition at the nearest
point in the class hierarchy, starting with the current class, is called.
You
must also use equivalent static type-name syntax to reference static
members of a class whose names are identical to reserved keywords, as
well as from inside the ABL class hierarchy, including when you
call event methods on inherited static class events.
For more
information on using static type-name syntax, see the appropriate
reference entry for the static member: Class-based data member access, Class-based method call, or Class-based property access. Also, for information on calling event methods
on a static event, see the Class Events Reference.
- ABL allows you to name an ABL class or interface using an ABL reserved
keyword, such as Display or DISPLAY. For a list of ABL reserved keywords,
see the Keyword Index.
However, this is not a recommended coding practice, in part because
ABL does not fully support the use of static type-name syntax for
a class or interface name that is an ABL reserved keyword. This
limitation is mitigated if the type name is a fully qualified type
name that includes both the package-name and
class name.
- Depending on the type definition, the context of the type reference, and the presence of
an appropriate USING statement, you can
use a qualified or an unqualified class, interface, or enum name to reference an ABL
object type. A qualified type name is one that includes both a
package-name and a class-interface-or-enum-name.
An unqualified type name is one that includes
class-interface-or-enum-name alone, without a
package-name. All qualified type names must be fully qualified, using
a complete package-name. ABL does not support partially qualified type
names using a partial package-name specification. Without an
appropriate USING statement, you can only specify an unqualified type name when the type
is defined directly on PROPATH (not in a package). In this case, the unqualified type name
is the complete type name for the object type.
Note: For classes with static
members, Progress Software Corporation recommends that you either define the class in a
package-name and always reference its static members using the
fully qualified class type name, or use a naming convention that defines static members
with unique names.
- Depending on the presence of an appropriate USING statement,
you can use a qualified or unqualified type name to reference a .NET type.
A qualified .NET type name is one that includes both a namespace and
a dotNET-object-name. An unqualified .NET type name
is one that includes dotNET-object-name alone,
without its defined namespace. All qualified .NET type
names must be fully qualified, using a complete namespace.
ABL (unlike .NET languages) does not support partially qualified
type names using a partial namespace specification.
Without an appropriate USING statement, you cannot specify an unqualified .NET type
name, because ABL does not support access to .NET types that
are defined in the .NET default namespace.
- You can reference a .NET delegate type only in the context
of a DEFINE EVENT statement.
- When you specify the type name of a class, interface, or enumeration in its ABL type
definition statement (CLASS, INTERFACE, or ENUM statement), and the class file where the
type is defined resides in a package directory, you must specify the qualified type name
(package-name.class-interface-or-enum-name) for its definition, even
with the presence of an appropriate USING statement. You can only specify an unqualified
type name (class-interface-or-enum-name alone) in its type definition
statement when the class file defining the type resides directly on PROPATH (is not in a
package directory).
- ABL allows a locally scoped name (for example, a variable, temp-table,
buffer name) to be identical to the name of an accessible class. If
this is the case, the locally scoped name takes precedence over
any static type-name reference to the unqualified class type name,
causing a compiler error on any such reference to a static class
member. To avoid this error, ensure that no locally scoped names
have the same name as the class, and always either use fully qualified
type-name syntax to reference the static class member or use naming
conventions to guarantee uniqueness for static member names.
- Because of the similarity between the syntax of object-type-name references
and table buffer and field references (including similarities between
syntax type-name references and field attribute references), ABL
can encounter ambiguous references among them, resulting in compilation
errors. To ensure that ABL always recognizes object-type-name references unambiguously,
either define all object type names with at least three period (.)
separators (in other words, at least three components in any package-name specification)
or use naming conventions to guarantee that object-type-name references
and database element references are unique. Otherwise, ABL recognizes
all such references as object-type-name references.
For
example, suppose that you have a user-defined class type in your PROPATH, Sports2000.Customer.Name, which
defines a static property, Label. The reference
in the following code fragment would then be ambiguous because ABL
cannot distinguish between a reference to this static Label property
and a reference to the LABEL attribute on the fill-in widget that
is defined for the Name field in the Customer table
of the Sports2000 database:
DEFINE VARIABLE cLabel AS CHARACTER NO-UNDO.
DEFINE FRAME a Sports2000.Customer.Name.
FIND FIRST Sports2000.Customer.
cLabel = Sports2000.Customer.Name:Label. /* Ambiguous reference */
|
- For more information on the types provided by Microsoft .NET,
see the .NET class library documentation available from the Microsoft® Development
Network (MSDN) at http://msdn.microsoft.com/en-us/library/aa338209.aspx.
Note: The .NET class library does not list nested
types as members (which they are) of the type that defines them.
Instead, it lists each nested type definition immediately following
the type that defines it. You can identify .NET nested types
in this listing by the period (.) that separates
the inner-name of the nested type name from the
name of the .NET type that defines it. As shown in this syntax
and examples, ABL uses a plus (+) instead of a period
(.) to reference the inner-name of
a nested type.
- To compile ABL references to a .NET type, the type must
be defined in either an automatically-loaded .NET assembly
or in a .NET assembly that is listed in an OpenEdge® assembly
references file named assemblies.xml. This
file must be available either in the working directory or in the
directory specified by the Assemblies (-assemblies)
startup parameter. You must also deploy this file at run time. For
more information on working with assembly references files, see OpenEdge
Development: GUI for .NET Programming. OpenEdge also loads
the following assemblies automatically if they are not referenced
in assemblies.xml:
- Progress.NetUI.dll — Assembly
where all custom OpenEdge .NET classes and interfaces reside
- Mscorlib.dll — Assembly
where all core Microsoft .NET classes and interfaces reside
- System.Windows.Forms.dll — Assembly
where all Microsoft form and control classes and interfaces reside
- System.Drawing.dll —
Assembly where basic Microsoft graphics classes and interfaces reside
The
point at which OpenEdge loads any .NET assemblies depends
on your application (see the following note on loading the CLR).
- OpenEdge loads the .NET Common Language Runtime (CLR)
and all required assemblies for access by ABL if any of the following
conditions exists:
- When you first reference a .NET type in a procedure or class file (compilable unit), ABL
is always case-sensitive when using your reference to identify and search for the type
definition. However, for names of .NET class members, including properties, data members,
methods, and enumeration members, ABL is case insensitive.
Note: Microsoft
recommends that .NET names never be distinguished by letter case, alone. However, if a
.NET class does have two class members with names distinguished only by letter case, ABL
finds only the first one defined in the class.
- For information on how ABL maps .NET types to ABL primitive types,
see the Data types reference
entry.
- When creating and accessing .NET arrays in ABL, you must
use methods of the .NET System.Array type.
ABL also supports automatic mappings between ABL and one-dimensional .NET arrays,
allowing supported .NET and ABL arrays to be assigned to each
other or passed to each other as routine parameters. For more information,
see the Data types reference entry.
- Note that you can specify an ABL array of .NET array objects,
which is equivalent to a two-dimensional array. The following example
defines an ABL array with 10 elements, each of which can reference
a one-dimensional .NET array of System.Drawing.Point objects:
DEFINE VARIABLE rPointArray AS CLASS "System.Drawing.Point[]"
EXTENT 10 NO-UNDO.
|
- You can also specify a constructed .NET generic type for dotNET-object-name.
ABL supports references to a .NET generic type for all uses
of .NET types except to specify a .NET class to inherit
or a .NET interface to implement in an ABL class definition.
For more information on constructing and using .NET generic
types in ABL, see the Data types reference entry.