Ich überlege, wie weit mir Generika helfen, meine Klassen zu verbessern. In folgendem Fall möchte ich meine Klasse TRecordList als generische Klasse implementieren. TRecordList verwaltet eine Liste Records. P soll der Typparameter sein, z.B. PMyRecord = ^TMyRecord. Problematisch sind die Zuweisungen der Zeiger aus der gekapselten Liste (property List: TList read FList) an Result: P (in GetItem) und von Value: P (in SetItem):
Delphi-Quellcode:
function TRecordList
.GetItem(const Index: Integer): P;
begin
Pointer(Result):=List[Index];
end;
procedure TRecordList
.SetItem(const Index: Integer; const Value: P);
begin
List[Index]:=Value;
end;
Problematisch ist, dass ich keine Möglichkeit kenne, die möglichen Typparameterwerte auf Zeiger einzugrenzen. Entprechend muss der Compiler die Zuweisungen bemängeln.
Kann man die Werte irgendwie eingrenzen? Oder, wie kann man Zuweisungen zwischen einem Zeiger und einer Variable "unbekannten Typs" (aber es soll ein Zeiger sein) durchführen?
Hier noch einmal der Quelltext im Zusammenhang, so wie ich mir das vorstelle (auf das Nötige gekürzt). Leider dürfte das in den Methoden GetItem, SetItem, GetRecordSize nicht funktionieren, wenn ich mir vorstelle, dass P eben nicht nur für einen Zeiger stehen kann, sondern auch für eine Zahl, einen String, eine Klasse, eine Schnittstelle,... ("Dürfte" deshalb, weil ich es selbst nicht probieren kann.)
Delphi-Quellcode:
unit RecordList;
interface
uses
Classes;
type
TRecordList
=
class
strict private
FList: TList;
strict protected
property List: TList
read FList;
function GetItem(
const Index: Integer): P;
function GetRecordSize: Integer;
procedure SetItem(
const Index: Integer;
const Value: P);
public
property Items[
const Index: Integer]: P
read GetItem
write SetItem;
default;
property RecordSize: Integer
read GetRecordSize;
constructor Create;
destructor Destroy;
override;
end;
TMyRecord =
record
{ ... }
end;
PMyRecord = ^TMyRecord;
TMyRecordList = TRecordList<PMyRecord>;
implementation
{ TRecordList
}
constructor TRecordList
.Create;
begin
inherited Create;
FList:=TList.Create;
end;
destructor TRecordList
.Destroy;
begin
List.Free;
inherited;
end;
function TRecordList
.GetItem(
const Index: Integer): P;
begin
Pointer(Result):=List[
Index];
end;
function TRecordList
.GetRecordSize: Integer;
begin
Result:=SizeOf(P^);
end;
procedure TRecordList
.SetItem(
const Index: Integer;
const Value: P);
begin
List[
Index]:=Value;
end;
end.