The name of an ABL or .NET object type that defines the specified property as a static member. The use of class-type-name to access a static property is optional when you access the property from within the class hierarchy where it is defined. For more information, see the notes for this reference entry. You cannot use class-type-name to access an instance property. For more information on specifying object type names, see the Type-name syntax reference entry. You can use the unqualified class name with the presence of an appropriate USING statement.
object-reference
Specifies a reference to an instance of an ABL or .NET class (an object) that defines the specified property as an instance member. The use of object-reference to access an instance property is optional when you access the property from within the class hierarchy where it is defined. For more information, see the notes for this reference entry. You cannot use object-reference to access a static property. For information on specifying object references, see the reference entry for a Class-based object reference.
property-name
The name of an ABL or .NET property. Accessing a property is similar to accessing a variable data member. Also, like a data member, a property is defined in, and at, the level of a class definition. If it is an instance property, a separate copy exists for each instance of its defining class, for as long as the class instance exists. If it is a static property, only one copy exists for the defining class type during the entire ABL session, regardless if any instance of the class exists. A property is available inside or outside of the class hierarchy depending on its access mode. If and how a property can be read or written depends on a combination of its access mode and associated behavior defined for the property. For more information on ABL property definitions, see the DEFINE PROPERTY statement reference entry. For information on the definition of a .NET property, see its entry in Microsoft .NET, Infragistics, or another class library that defines it.
[ index|key ]
An index specifies an index into an ABL array property. A key specifies an indexer for a .NET indexed property. The brackets are a required part of the syntax.
If an array index is specified, it can be an integer value that identifies an element of an ABL array property, similar to an element of an ABL array data member (see the Class-based data member access reference entry).
If a key for a .NET property indexer is specified, it can be a value of any supported .NET data type that identifies the property value to reference. A .NET indexed property represents a group of properties, where the key is a value that indicates what member of the group is being referenced. A .NET indexed property can have more than one type of indexer that is overloaded according to the data type of its key, similar to a method that is overloaded by a single parameter. However, you cannot specify an AS data type with the key in order to identify a particular .NET indexer overload, as you can with a .NET method parameter (see the Parameter passing syntax reference entry). Also, some .NET indexed properties have indexers with multiple key values, each with its own data type. However, ABL only supports .NET indexed properties that have single-key indexers. So, you might be able to use some indexers for a property and not be able to use others.
Thus, ABL only recognizes a .NET property indexer if the property has a single-key indexer. If so, ABL selects the indexer using the ABL data type that you specify for the key, in order by the following criteria:
1. If the .NET data type of an indexer key is the default match for the specified ABL data type, ABL uses that key.
2. If there is no .NET indexer key that is a default match for the specified ABL data type, ABL uses the first key that it encounters where the .NET data type is an implicit data type mapping for the specified ABL data type.
For more information on how ABL data types map to .NET data types, see the Data types reference entry.
For example, if you specify an ABL INTEGER value for the key, and the indexer is overloaded by .NET System.Double, System.Byte, and System.Int32 keys, ABL uses the System.Int32key to index the property. If the available overloadings are System.Double, System.Byte, and System.Int16, ABL uses either the System.Byte or the System.Int16key, which ever is encountered first.
ABL classes do not currently support the definition of indexed properties. So, you cannot access ABL properties using an indexer.
Examples
The following code fragment shows a reference to a public instance property (HighCustBalance) on an instance of the sample class, r-CustObj:
DEFINE VARIABLE rObj AS CLASS r-CustObj NO-UNDO.
rObj = NEW r-CustObj( ) NO-ERROR.
This static property similarly returns the highest balance for all Customer records in the sports2000 database without having to instantiate the class, as in the previous instance code.
For more information on these properties and the sample classes in which they are defined, see the examples in the CLASS statement reference entry.
Notes
Using the appropriate property syntax, if the property is defined as both readable and writable, you can assign and otherwise read and write the value of a property in the same way as a variable data member of the same data type. If the property is read-only, you can only read the property value; if the property is write-only, you can only write a value to the property. For information on how .NET data types map to ABL data types when using .NET properties, see the Data types reference entry.
When and how the value of a property can be read or written depends on the definition of special methods (accessors) that execute during property access. For more information on accessors for ABL properties, see the DEFINE PROPERTY statement reference entry. Note that even though the value written to a property appears to its SET accessor like a method parameter, the compatibility between the data type of the written value and the data type of the property follows the same rules as the assignment of data types for variables or data members. In other words, ABL attempts to identify an appropriate conversion when you assign a value to a property. For more information, see the Assignment (=) statement reference entry.
For more information on accessors for a .NET property, see its entry in Microsoft .NET, Infragistics, or another class library that defines the property. In C# documentation, the presence of a get accessor in the property signature means that the property is readable; the presence of a set accessor in the property signature means that the property is writable. For example, the signature of the .NET HelpButton property indicates that it is both readable and writable, because it shows both a get and a set accessor:
public bool HelpButton { get; set; }
If the property is defined as static, you can access the property whether or not an instance of its defining class exists.
If you reference an available property within a static constructor, static method, or static property accessor that is defined in the same class or class hierarchy as the referenced property, the referenced property must also be defined as static; attempting to reference an instance property that is defined in the same class or class hierarchy as a referencing static member raises a compile-time error.
In ABL, all private and protected properties are class based. A property marked as PRIVATE can be accessed from any instance of the class that defines it. Likewise, a PROTECTED property can be accessed from any instance of the defining class or subclass. In other words, an instance can access the PROTECTED property of a second instance of a class that is at the same level or higher in the class hierarchy.
From within an ABL class definition, you can reference any property that is both defined and available within the class hierarchy using its property-name without a qualifying object-reference (for instance properties) or class-type-name (for static properties). Optionally, you can use the THIS-OBJECT system reference as an object-reference to access any available instance property defined within the class hierarchy. If the property name is a reserved keyword, you must reference the property by qualifying the name with either its class-type-name or THIS-OBJECT as the object-reference. For more information, see the reference entry for the THIS-OBJECT system reference.
From outside a class hierarchy, you must reference any available property using its property-name qualified by an object-reference to the class instance where the property is defined. You can only reference an available static property by referencing its property-name qualified by the class-type-name of the class that defines the property as static. The only properties defined in a class hierarchy that are available outside the hierarchy are properties defined as PUBLIC.
You can access an abstract property either from within the class that defines it or on an object-reference defined as the type of the abstract class that defines it. Although an abstract property is defined without an implementation, at run time, the property is always implemented in a derived class. So, any reference to an abstract property is always resolved by the derived class that implements it.
When you access an ABL property from within its own definition (from an accessor), this access either directly accesses the property's default memory or invokes an accessor, depending on whether you are reading or writing the property and which accessor you are accessing the property from. For more information, see the DEFINE PROPERTY statement reference entry.
.NET indexed properties can be overloaded only by the indexer, and ABL identifies the overloading to use only by the definition of its indexer. Each overloading of an indexed property can specify a different access mode (for example, private or public) and can have different accessor method definitions. For example, one overloading of a property might be read-only and another overloading of the property might be write-only. In general, all overloadings of an indexed property share the same property data type. However, the data type of the index key does not have to match the data type of the property.
A .NET class can have a default indexed property. By convention, most default indexed properties in the .NET Framework are named Item. Like some .NET languages, ABL allows you to access the default indexed property by its name, like any other property. However, ABL also allows you to access the default indexed property of a class by specifying the indexer directly on object-reference, omitting the property name (see the Class-based object reference reference entry in this book). For example, the .NET System.Data.DataView class defines a default Item property that returns a .NET DataRow given a record index. In ABL, therefore, the following indexed object references to a DataView class instance are identical:
DEFINE VARIABLE rDataView AS CLASS System.Data.DataView.
DEFINE VARIABLE rRow AS CLASS System.Data.DataRow.
. . .
rRow = rDataView[2].
rRow = rDataView:Item[2].
In .NET, the most common use of a default indexed property is to access an instance of a class from a collection. Two examples are the .NET System.Data.DataTableCollection and the System.Data.DataRow classes. For more information on working with .NET collections in ABL, see OpenEdge Development: GUI for .NET Programming.
When you access a property, the property accessor can raise the ERROR condition on the statement that accesses the property. If this statement is defined with the NO-ERROR option, you can locate the property error information using the ERROR-STATUS system handle following statement execution, and you can read any returned error string using the RETURN-VALUE function. Alternatively, you can catch the property error object using a CATCH statement in the block that executes the statement. To access more comprehensive error information for a .NET exception, use a CATCH statement instead of the NO-ERROR option to handle .NET exceptions raised from accessing .NET properties. For more information on handling .NET exceptions, see the sections on .NET error handling in OpenEdge Development: GUI for .NET Programming.