Generics

Top  Previous  Next

Generics in .NET programming refers to a class that is not related to any specific Type, but is still used in a Type-Safe manner. A perfect example of where Generics are useful is with collections of items (integers, strings, Orders etc.). We can create a generic collection than can handle any Type in a generic and Type-Safe manner. For example, we can have a single array class that we can use to store a list of Users or even a list of Products, and when we actually use it, we will be able to access the items in the collection directly as a list of Users or Products, and not as objects.

The use of generic classes is supported in Clarion#.

 

To use generic types/methods, specify generic arguments (types) in angle brackets.( <…>).

 

Examples:

 

Aa  &List<Int32>     !declaration of variable with generic List type with Int32 argument

 

bb.cc<String>('aaa') !generic method call cc with generic String argument

 

There are two restrictions:

1. Arrays can’t be used as a generic argument

2. All .Net reference types are considered as reference and .Net value-types are considered as values. Using of types with & (such as &LONG) in generic arguments are not supported

 

Declaration of generics

To declare a generic CLASS, STRUCT, or INTERFACE you should add generic parameters in angle brackets (e.g., < >) just after the appropriate keyword. Constraints for generic parameters can be specified with a WHERE(…) clause. The list of WHERE clauses (without any delimiters) should be placed before all attributes.

 

The syntax of the WHERE clause is as follows:

 

WHERE(<generic argument name>=(constraint1,constraint2…,constraintN)

 

Where constraint has the following syntax:

 

   NEW|CLASS|STRUCT|<type>

 

NEW

The generic argument should have default constructor

CLASS

The generic argument should be reference type

STRUCT

The generic argument should be value type

<type>

The generic argument should be inherited from the <type>

 

In the generic method definition the class label uses the following syntax:

 

Notes:

1.

CLASS and STRUCT constraints can’t be used simultaneously.

2.

If <type> is a STRUCT or CLASS, then STRUCT and CLASS constraints can’t be used.

3.

When calling the generic method, the explicit <type> is superfluous, if the passed parameter is already of the desired class.

 

 

In the method definition for a Generic the class label has the following syntax:

 

Name <generic parameter1,…, generic parameterN>

 

Example:

 

PROGRAM

NAMESPACE qqq

USING System

           

           

aa CLASS<T,V> WHERE(T=ICloneable)

mm  PROCEDURE

bb  PROCEDURE(T b)

vv  PROCEDURE(T b,V e)

    INLINE

     CODE

      MESSAGE(b.Clone())

    END

  END

 

 CODE

 

aa<T,V>.mm   PROCEDURE

ee  &ICloneable

bb1 T

 CODE

 ee = bb1

 SELF.bb(bb1)

 MESSAGE(bb1.Clone())

 

aa<T,V>.bb   PROCEDURE(T b)

 CODE

 

 

To declare generic methods place the generic parameters of the procedure in <…> and add constraints (WHERE clause before any attributes of the procedure)

 

Example:

Bb    PROCEDURE<T>(T arg) WHERE(T=NEW)

 

 

Current restrictions in using generic parameters:

 

1. If T is a generic parameter then the following declarations are equivalent:

 

Clarion#

C#

Aa T

T aa;

 

No instance is created and no constructor is called. It’s just a declaration of a variable.

 

The following declaration syntax:

 

Aa &T

 

is currently not supported.

 

2. If the left or right part of the assignment statement has a type T, where T is a generic parameter, you need to use the = assignment operator (not &=).

 

For example:

 

Aa  T

Bb  T

  CODE

  AA = Bb

 

DEFAULTOF

 

You can also generate a default value for a type in a generic declaration.

 

The special expression:

 

 DEFAULTOF (<type>)

 

is used for this purpose.

 

The expression generates a default value for the corresponding type. For value-types, it’s value with zeros (0) and for reference types it’s just a null reference. For more information see the default keyword in C# documentation.

 

Example:

 

A  T

    CODE

    A=DEFAULTOF(T)

 

See Also: Variable Declaration outside of the DATA section