A generic type is one programming construct that adapts to do the same operations for many data types. When you write generic code, it is not necessary to write different implementations for each possible data type.
Example generic class
Class Container[T] Method Add(item As T) Dim temp As T End Method End Class
Permitted generic constructs
You can make and use generic classes, structures, traits, and procedures. The ViviFire standard libraries supply many frequently used generic constructs that you can use in your code.
Although procedures are not types, you can make and use generic procedures. See Generic Procedures for more information.
How generic types help
You use generic types to declare some different programming elements, where each one operates on the specified data types. The alternatives to a generic type are:
- One type operates on the object data type.
- A set of different implementations of the type, each coded differently to operate on one data type, for example,
String, or a user-made class or structure.
Generic types are better than these alternatives because of:
- Type safety – Generic types let the compiler do type checking. The compiler can find type errors.
- Performance – It is not necessary for generic types to box and unbox data. Each one is specially made for one data type.
- Decreased code – You write the code in a generic type only one time. If you make implementations of a type for each data type, then you must write the same code again and again. Their only differences are the data types they use. But generic types automatically make implementations for each data type.
- Code that you can use again – TODO
- Generic algorithms – TODO
You must try to write The code for a generic construct as disconnected from types as possible.
But some functions can be necessary to have for data types supplied to your generic construct.
For example, to compare two items to sort them, their data type must implement the trait
To do this, you can add a constraint for the type parameter.
Example of a constraint
The example that follows shows a skeleton of a generic class with a constraint.
The constraint makes it necessary for the type argument to implement
Class GenericClass[T] Where T Does Compare ' ... End Class
If you try to use
GenericClass with a type that does not implement
Compare, then the compiler gives an error.
Types of constraints
Your constraint can specify the requirements that follow:
- The type argument must be one in a given branch of inheritance.
- The type argument must be one of a reference type, a value type, or a unit of measure.
- The type argument must implement one or more traits.
- The type argument must have a constructor without parameters.
- The class that uses a trait must inherit from a given class.
If you must specify more than one requirement, then you can put a comma between each one.
But if a constraint makes a line of code too long, then you can divide it into many constraints.
you can use
Where again and again, each on a different line.
But the shortest constraint can use a type parameter a minimum of one time. Then you must put the requirements in the sequence given above.
- If a sub-type is necessary, then use one of the operators
- If a reference type is necessary, then use «
- If a value type is necessary, then use «
- If a unit of measure is necessary, then use «
- If a trait is necessary, then use «
- If a constructor is necessary, then use «
Constructor()». The parentheses are mandatory.
See Where Clause (Generics) for more information.
Examples of many constraints
The examples that follow show a skeleton of a generic class with three constraints on the type parameter.
The type argument must (1) be a reference type, (2) implement
Compare, and (3) have a constructor without parameters.
All three examples are equivalent.
Example 1 uses the shortest construct with
Where on the same line as the start of the class.
Class MyClass[T] Where T Is Class Does Compare Constructor() ' ... End Class
Example 2 uses the construct with commas between requirements all on one line in the class body.
Class MyClass[T] Where T Is Class, T Does Compare, T Constructor() ' ... End Class
Example 3 uses three different lines that start with
Where in the class body.
We wrote the requirements in a sequence different from the other examples.
Class MyClass[T] Where T Constructor() Where T Does Compare Where T Is Class ' ... End Class