Einzelnen Beitrag anzeigen

Panthrax

Registriert seit: 18. Feb 2005
286 Beiträge
 
Delphi 2010 Enterprise
 
#1

Zeiger als Parameter eines generischen Typs, TRecordList

  Alt 30. Mär 2009, 10:44
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.
"Es gibt keine schlimmere Lüge als die Wahrheit, die von denen, die sie hören, missverstanden wird."
  Mit Zitat antworten Zitat