I have been given special permission to discuss or show Highlander, and will post some Highlander Beta Blogging articles in next couple of days - starting with the coverage of Generics in Delphi for .NET. I'm using a pre-release Beta, but you can expect things to work pretty much as outlined below.
Generics are also known as parameterised types, which actually describes more clearly what's going one: a type definition with one or more parameters (where the parameters can be types so the definition itself is considered to be a generic definition). As syntax for the parameter, Delphi for .NET uses <T>.
A very simple example of a generic array can be coded in Highlander as follows:
type
Some<T> = Array of T;
We can declare variables by specifying a type for the <T>, such as:
type
SomeIntegers = Some<integer>;
var
X: SomeIntegers;
This is still only a generic data definition, and adds no function. So it's really limited in its benefit. A more useful example, showing benefit in using a parameterised type, comes when considering a class with methods, such as a queue.
The definition of a generic TQueue could be:
type
TQueue<AnyType> = class
protected
FList: System.Collections.Generic.List<AnyType>;
public
constructor Create;
destructor Destroy; override;
function Count: Integer;
function AtLeast(count: Integer): Boolean;
function Push(const itemT: AnyType): AnyType;
function Peek: AnyType;
function Pop: AnyType;
end;
The implementation of the TQueue methods also use a new <T> syntax, as follows:
constructor TQueue<AnyType>.Create;
begin
inherited Create;
FList := System.Collections.Generic.List<AnyType>.Create
end;
destructor TQueue<AnyType>.Destroy;
begin
FList.Free;
inherited Destroy
end;
The actual Queue member functions mainly make use of the generic list which is in .NET 2.0 already, but they do help to illustrate the declarative power of generics. Whether we want to have a queue of integers or a queue of print jobs or mail messages, the TQueue class can be used just the same.
function TQueue<AnyType>.Count: Integer;
begin
Result := FList.Count
end;
function TQueue<AnyType>.AtLeast(count: integer): Boolean;
begin
Result := FList.Count >= count
end;
function TQueue<AnyType>.Push(const itemT: AnyType): AnyType;
begin
FList.Insert(0, itemT);
Result := itemT
end;
function TQueue<AnyType>.Peek: AnyType;
begin
Result := FList[FList.Count-1]
end;
function TQueue<AnyType>.Pop: AnyType;
begin
Result := Peek;
FList.RemoveAt(FList.Count-1)
end;
Using the generic TQueue class in Highlander is done as follows:
type
TStringQueue = TQueue<string>;
var
S: TQueue<string>;
begin
S := TStringQueue.Create;
try
S.Push('Delphi 2007 for Win32');
S.Push('C++Builder 2007');
S.Push('Highlander (aka Delphi 2007 for .NET)...');
writeln(S.Pop);
writeln(S.Pop);
writeln(S.Pop);
finally
S.Free
end
end.
Note that I've used a String queue, but you can add anything to the generic queue.
All in all, a very powerful feature of .NET, and soon available to Delphi for .NET developers when Highlander is released.