AGB  ·  Datenschutz  ·  Impressum  







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

Generic record

Ein Thema von bernhard_LA · begonnen am 5. Mär 2012 · letzter Beitrag vom 5. Mär 2012
Antwort Antwort
Seite 1 von 2  1 2      
bernhard_LA

Registriert seit: 8. Jun 2009
Ort: Bayern
1.138 Beiträge
 
Delphi 11 Alexandria
 
#1

Generic record

  Alt 5. Mär 2012, 11:42
Ich möchte mit Hilfe von GENERICS beliebige Records in ein ByteArray und wieder zurück umwandeln .
Für die Lösung wollte ich zum ersten mal GENERICS in Delphi verwenden.

Der Code unten spielt wenn ich anstelle von TGenericRecord eine beliebige Record Definition direkt einsetze.
Habe ich einen Denkfehler in meinem Ansatz ?




Delphi-Quellcode:

type
   TGenericRecord <TRecordType> = class
              /// value : TRecordType;
   end;


///
/// --------------- HELPER FUNCTION FOR RECORD EXCHANGE ------------------
///

function MyRecordToByteArray(aRecord: TGenericRecord): TBytes;
var
  LSource: PAnsiChar;
begin
  LSource := PAnsiChar(@aRecord);
  SetLength(Result, SizeOf(TGenericRecord));
  Move(LSource[0], Result[0], SizeOf(TGenericRecord));
end;

function ByteArrayToMyRecord(ABuffer: TBytes): TGenericRecord;
var
  LDest: PAnsiChar;
begin
  LDest := PAnsiChar(@Result);
  Move(ABuffer[0], LDest[0], SizeOf(TGenericRecord));
end;
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.314 Beiträge
 
Delphi 12 Athens
 
#2

AW: Generic record

  Alt 5. Mär 2012, 11:49
Dein genric Record ist eine generic Class

TGenericRecord<x> entspricht nicht TGenericRecord

function MyRecordToByteArray<X>(aRecord: TGenericRecord<x>): TBytes; , da aber keine generischen Prozeduren möglich sind, muß dieses eine Methode eines Records oder eines Objekts werden.

statt
Zitat:
SizeOf(TGenericRecord)
muß es dann statt
Zitat:
SizeOf(TGenericRecord<X>)
werden, oder einfach nur statt
Zitat:
SizeOf(aRecord)
.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.039 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#3

AW: Generic record

  Alt 5. Mär 2012, 12:06
Ich glaub, du möchtest so etwas:

Delphi-Quellcode:
type
  TRecordSerializer = class
    class function ToByteArray<T: record>(const Value: T): TBytes; static;
    class function ToRecord<T: record>(const Value: TBytes): T; static;
  end;

class function TRecordSerializer.ToByteArray<T>(const Value: T): TBytes;
begin
  SetLength(Result, SizeOf(T));
  Move(Value, Result[0], SizeOf(T));
end;

class function TRecordSerializer.ToRecord<T>(const Value: TBytes): T;
begin
  Move(Value[0], Result, SizeOf(T));
end;
Denke aber bei diesem Ansatz auf jeden Fall daran, dass du damit keine managed types (z.B. string) behandeln kannst. Denn in dem Record befindet sich in diesem Fall nur ein Pointer auf den string.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
bernhard_LA

Registriert seit: 8. Jun 2009
Ort: Bayern
1.138 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Generic record

  Alt 5. Mär 2012, 12:38
@ Stevie : in meinen records können leider auch Strings vorkommen .... kann damit Deine Lösung nicht verwenden
@ Himitsu : wenn ich keine Generic Typs als Funktions Rückgabewert verwenden kann --> dann muss ich wohl auf das gute & alte
function overloading zurückgreifen ;



im Code unten maul der Compiler "TRecordType" kennt er nicht, ist doch klar.... kenne ich gerade selbst noch nicht .... sage ich dem Compiler schon und zwar dann wenn ich die Funktion auch verwenden will .... mit TGenericRecord<TAnwerndungsrecord>.Create, solange soll er halt warten


Delphi-Quellcode:

function MyRecordToByteArray(aRecord: TGenericRecord<TRecordType>): TBytes;
var
  LSource: PAnsiChar;
begin
  LSource := PAnsiChar(@aRecord);
  SetLength(Result, SizeOf(TMyRecord));
  Move(LSource[0], Result[0], SizeOf(TGenericRecord<TRecordType>));
end;

function ByteArrayToMyRecord(ABuffer: TBytes): TGenericRecord<TRecordType>;
var
  LDest: PAnsiChar;
begin
  LDest := PAnsiChar(@Result);
  Move(ABuffer[0], LDest[0], SizeOf(TGenericRecord<TRecordType>));
end;
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.314 Beiträge
 
Delphi 12 Athens
 
#5

AW: Generic record

  Alt 5. Mär 2012, 13:00
Zurückgeben kann man es, aber function MyFunction<T>(...): ...; ist nicht möglich ... das geht leider nur bei Methoden (Record oder Object).
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
bernhard_LA

Registriert seit: 8. Jun 2009
Ort: Bayern
1.138 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Generic record

  Alt 5. Mär 2012, 13:11
was Delphi auf nicht compiliert

Delphi-Quellcode:

type TRecordTypeA= ....
     ....
     ...
     ..


// gib mir ein record type 1 zurück
function testfunction (a : Integer) : TRecordTypeA; overload;
// nun type 2
function testfunction (a : Integer) : TRecordTypeB; overload;
// usw ....
function testfunction (a : Integer) : TRecordTypeC; overload;


müsste ich etwas wie
Delphi-Quellcode:

procedure (a : Integer; var TGenericRecordType<T> );
codieren.


bzw.
Zitat:
da aber keine generischen Prozeduren möglich sind, muß dieses eine Methode eines Records oder eines Objekts werden


TGenericTRecord <TRecordtype>= class

function ByteArrayToMyRecord(ABuffer: TBytes): TRecordtype
end;

Geändert von bernhard_LA ( 5. Mär 2012 um 13:18 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.039 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#7

AW: Generic record

  Alt 5. Mär 2012, 13:44
@ Stevie : in meinen records können leider auch Strings vorkommen .... kann damit Deine Lösung nicht verwenden
Ja, genau wie alle anderen Ansätze in diesem Thread, die auf SizeOf, Move und ähnlichem basieren
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Pitschki1801

Registriert seit: 9. Feb 2012
14 Beiträge
 
Delphi XE Professional
 
#8

AW: Generic record

  Alt 5. Mär 2012, 14:44
schau mal hier rein vllt bringt dich das weiter Tut-Generics
  Mit Zitat antworten Zitat
Panthrax

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

AW: Generic record

  Alt 5. Mär 2012, 15:15
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.
Angehängte Dateien
Dateityp: pas Thema1154552.dpr.pas (1,7 KB, 1x aufgerufen)
"Es gibt keine schlimmere Lüge als die Wahrheit, die von denen, die sie hören, missverstanden wird."
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.039 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#10

AW: Generic record

  Alt 5. Mär 2012, 16:10
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.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 13:50 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 by Thomas Breitkreuz