Einzelnen Beitrag anzeigen

Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.582 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: Kopieren des Inhalt eines Record

  Alt 20. Okt 2013, 10:18
@Bjoerk:
Ohne Generics macht das ganze nicht so viel Sinn.
Und Clear kannst du auch problemlos in einen Record einbauen...


Ein komplettes Beispiel mit einigen der Möglichkeiten findest du hier.

Ein Vorteil ist, dass du dich nicht selbst um die Pointer kümmern musst. Du hast einfach immer eine Referenz, also einen impliziten Pointer, und fertig. Für das Zuweisen der Werte kannst du, wenn du von TPersistent ableitest, Assign oder AssignTo überschreiben (oder du implementierst es als normale Methode neu, wenn du von TObject ableitest).
Vorteil des Überschreibens von AssignTo:
Es wird schon vorher geprüft, ob nil übergeben wurde und ggf. ein qualifizierter Fehler ausgelöst und wenn die falsche Klasse zugewiesen wird, brauchst du nur inherited aufrufen und es kommt auch ein qualifizierter Fehler.

Du musst keine Properties verwenden, du kannst es also auch genauso schreiben wie du es bei Records hattest (die heute aber auch Properties kennen), aber die haben den Vorteil, dass die privaten Felder nicht direkt erreichbar sind und du ggf. leicht Setter oder Getter einbauen kannst.

Ein wenig mehr Quelltext ist es in der Klasse oft schon, aber dafür ist die Verwendung sehr viel einfacher. In der Praxis wird die Anzahl der Verwendungen sehr viel höher sein als die einmalige Implementierung der Klasse, so dass es sehr viel sinnvoller ist die Verwendung zu vereinfachen als bei der Implementierung der Klasse selbst zu sparen.
Delphi-Quellcode:
unit Unit15;

interface

uses
  System.Generics.Collections, System.Classes, Vcl.Dialogs;

procedure Test;

implementation

type
  TTest = class(TPersistent)
  private
    var
      FString1: String;
      FString2: String;
      FDouble1: Double;
  protected
    procedure AssignTo(Dest: TPersistent); override;
  public
    constructor Create(const AString1: string; const AString2: string = ''; const ADouble1: Double = 0.0); overload;
    constructor Create(const ACloneSource: TTest); overload;
    property String1: String read FString1 write FString1;
    property Double1: Double read FDouble1 write FDouble1;
    property String2: String read FString2 write FString2;
  end;

  TMyList = class(TObjectList<TTest>)
  public
  end;

procedure Test;
var
  Test: TMyList;
  Current: TTest;
begin
  Test := TMyList.Create(True);
  try
    Test.Add(TTest.Create('Test 1'));
    Test.Add(TTest.Create('Test 2'));
    Test.Add(TTest.Create('Hallo'));
    Current := TTest.Create('Clone Source');
    try
      Test.Add(TTest.Create(Current)); // Neues Objekt aus Current erzeugen
    finally
      Current.Free;
    end;

    for Current in Test do
      ShowMessage(Current.String1); // alle ausgeben

    // zuweisen
    Current := TTest.Create;
    try
      Current.Assign(Test[2]);
      ShowMessage(Current.String1); // Hallo
    finally
      Current.Free;
    end;
  finally
    Test.Free; // Die Objekte in der Liste werden durch das True für OwnsObjects im Konstruktor freigegeben
  end;
end;

{ TTest }

procedure TTest.AssignTo(Dest: TPersistent);
var
  Destination: TTest;
begin
  if Dest is TTest then
  begin
    Destination := TTest(Dest);
    Destination.String1 := FString1;
    Destination.String2 := FString2;
    Destination.Double1 := FDouble1;
  end
  else
    inherited;
end;

constructor TTest.Create(const AString1: string; const AString2: string = ''; const ADouble1: Double = 0.0);
begin
  FString1 := AString1;
  FString2 := AString2;
  FDouble1 := ADouble1;
end;

constructor TTest.Create(const ACloneSource: TTest);
begin
  Assign(ACloneSource);
end;

end.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat