Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Generic record (https://www.delphipraxis.net/166902-generic-record.html)

Stevie 5. Mär 2012 14:06

AW: Generic record
 
Da du in deinen records shortstrings (string[n]) benutzt, geht die von mir vorgeschlagene Lösung sehr wohl.

Hat auch den Vorteil, dass du keinen extra Datentyp (die Wrapperklasse für den Record) brauchst:

Delphi-Quellcode:
var
  a_record : TMyRecordA;
  b_record : TMyRecordB;
  c_record : TMyRecordC;

  ABuffer : TBytes;
begin
  // ein paar werte zuweisen .....
  a_record.Details := '#1 bla bla';
  a_record.FileName := '#2 bla bla';
  a_record.Recordsize := 100;
  a_record.FileSize := 222;


  b_record.x := 1;
  b_record.y := 2;
  b_record.z := 3;


  // im buffer daten zwischenlagern
  ABuffer := TRecordSerializer.ToByteArray<TMyRecordA>(a_record);
  // du kannst in diesem Fall das <TMyRecordA> auch weglassen,
  // da der Compiler das durch den Typen des übergebenen Parameter erkennt
  // Stichwort Type Inference


  // löschen oder mit anderen daten arbeiten
  a_record.Details := '.....';
  a_record.FileName := '----';
  a_record.Recordsize := -1;
  a_record.FileSize := -2;


  // Daten wieder aus dem Buffer zurücklesen
  a_record := TRecordSerializer.ToRecord<TMyRecordA>(ABuffer);


  // alte daten sind wieder da :-)
  memo1.lines.add( a_record.Details);
  memo1.lines.add( a_record.Filename);
end;

Panthrax 5. Mär 2012 14:15

AW: Generic record
 
Liste der Anhänge anzeigen (Anzahl: 1)
Delphi-Quellcode:
type
  { Generika sind nicht nötig: }
  TMeinRecord = record
    Value: TBeliebigerFeldtyp;
    // mehr beliebige Feldtypen

    class operator Implicit(const Value: TMeinRecord): TBytes;
    class operator Implicit(const Value: TBytes): TMeinRecord;
  end;

class operator TMeinRecord.Implicit(const Value: TMeinRecord): TBytes;
var
  Size: NativeInt;
begin
  Size := SizeOf(Value);

  SetLength(Result, Size);

//  if Size > 0 then
    Move(Value, Result[0], Size);
end;

class operator TMeinRecord.Implicit(const Value: TBytes): TMeinRecord;
var
  Size: NativeInt;
begin
  Size := Length(Value) { entspricht Größe in Bytes };

  if Size <> SizeOf(Result) then
    raise Exception.Create('Ungültige Feldgröße');

  Move(Value[0], Result, Size);
end;
Eine Konsolenanwendung ist beigefügt.

Stevie 5. Mär 2012 15:10

AW: Generic record
 
Zitat:

Zitat von Panthrax (Beitrag 1154592)
Generika sind nicht nötig

Das Problem ist bei dir, dass du für jeden Recordtyp diesen Code schreiben musst. Mit Generics kannst du eben dieses vermeiden, da die entsprechenden Umwandlungsfunktionen mit jedem beliebigen Record arbeiten.

Panthrax 5. Mär 2012 15:49

AW: Generic record
 
Ja, stimmt,
Delphi-Quellcode:
Move
arbeitet mit keinem (und deshalb mit jedem) (Feld-) Datentyp. Im angehängten Quelltext ist das auch bemerkt. Ich wollte nicht fragen, wofür man das braucht, obwohl ich diese Frage wirklich im Kopf habe. (Bitte keine Antworten.) Stattdessen habe ich mich entschieden, etwas vorzuschlagen.

Wenn man es auf Feldtypen allgemein ausrichten will:
Delphi-Quellcode:
type
  Fieldtype = record
    class function ToBytes(const Value; const Size: NativeInt): TBytes; overload; static;
    class function ToBytes<T>(const Value: T): TBytes; overload; static;
    class function FromBuffer<T>(const Value; const Size: NativeInt): T; static;
    class function FromBytes<T>(const Value: TBytes): T; static;
  end;
Irgendwie sind alle Aufrufe schon ziemlich nah am
Delphi-Quellcode:
Move
...


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:04 Uhr.
Seite 2 von 2     12   

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz