AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Kopieren des Inhalt eines Record

Ein Thema von DelphiFan2008 · begonnen am 18. Okt 2013 · letzter Beitrag vom 20. Okt 2013
Antwort Antwort
DelphiFan2008

Registriert seit: 4. Dez 2008
84 Beiträge
 
Delphi XE2 Starter
 
#1

AW: Kopieren des Inhalt eines Record

  Alt 20. Okt 2013, 07:17
@jaenicke,

danke für die Antworten. Frage: Wie würde denn ein alternativer Ansatz mit TObjectList<TTest> in diesem Fall aussehen. Mir fehlt die Erfahreung mit neueren Konstrukten. Arbeite noch immer vorwiegend mit Record, Pointer und den Basisklassen welche schon ab etwa Delphi3 bekannt sind und welchen Vorteil hätte ich?

Gruß DelphiFan2008
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Kopieren des Inhalt eines Record

  Alt 20. Okt 2013, 08:59
ObjectLists sind (im Gegensatz zu Records) vergleichsweise problemlos und einfach zu handhaben. Ich hab noch Delphi2007, deshlab muß ich die property Items überschreiben (brauchst du bei <TTest> nicht).

Delphi-Quellcode:
uses
  .. Contnrs;

type
  TTest = class
  private
    FD1: Double;
    FN1: Int64;
    FI1: Integer;
    FL1: LongInt;
    FS1: String;
    FS2: String;
    FS3: String;
  public
    property D1: Double read FD1 write FD1;
    property N1: Int64 read FN1 write FN1;
    property I1: Integer read FI1 write FI1;
    property L1: LongInt read FL1 write FL1;
    property S1: String read FS1 write FS1;
    property S2: String read FS2 write FS2;
    property S3: String read FS3 write FS3;
    procedure Clear;
    procedure Assign(Value: TTest);
  end;

  TTestList = class(TObjectList)
  private
    function GetItems(Index: integer): TTest;
  public
    property Items[Index: integer]: TTest read GetItems; default;
  end;

..

{ TTest }

procedure TTest.Assign(Value: TTest);
begin

end;

procedure TTest.Clear;
begin

end;

{ TTestList }

function TTestList.GetItems(Index: integer): TTest;
begin
  Result := TTest(inherited Items[Index]);
end;

..

var
  TestList: TTestList;
  Index: integer;
begin
  TestList := TTestList.Create;
  try
    // Hinzufügen von Items;
    Index := TestList.Add(TTest.Create);
    TestList[Index].Clear; // Das z.B. ginge bei einem Record nicht
    TestList[Index].S1 := 'Hello TObjectList';
    // Löschen von Items;
    TestList.Delete(Index);
  finally
    TestList.Free;
  end;
end;

Geändert von Bjoerk (20. Okt 2013 um 09:01 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
10.062 Beiträge
 
Delphi 12 Athens
 
#3

AW: Kopieren des Inhalt eines Record

  Alt 20. Okt 2013, 09: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
AppCentral
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Kopieren des Inhalt eines Record

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


Und was, wenn ich keine Generics hab?

Und, Records hatten wir beide doch grad letztens? Clear (bei TList) würde auf einer Kopie ausgeführt und im Nirwana verschwinden. Auch der Zugriff auf die einzelnen Felder wäre so nicht möglich?
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
10.062 Beiträge
 
Delphi 12 Athens
 
#5

AW: Kopieren des Inhalt eines Record

  Alt 20. Okt 2013, 10:27
Und was, wenn ich keine Generics hab?
Dann macht es für dich Sinn, aber für ihn nicht, da er sie mit XE2 hat...

Und, Records hatten wir beide doch grad letztens? Clear (bei TList) würde auf einer Kopie ausgeführt und im Nirwana verschwinden. Auch der Zugriff auf die einzelnen Felder wäre so nicht möglich?
Aber nicht bei Pointerzugriffen wie in meinem Beispiel mit TList<PTest>, da geht das durchaus.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:42 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz