Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Ableiten von Records (https://www.delphipraxis.net/156533-ableiten-von-records.html)

SirThornberry 6. Dez 2010 09:22

Delphi-Version: 2010

Ableiten von Records
 
Ist es inzwischen möglich von Records abzuleiten und wenn ja - wie?

Es geht um folgendes. Ich habe einen Record (TRecordBase) mit verschiedenen Funktionen etc.
Jetzt benötige ich an bestimmten Stellen noch weitere Informationen die nicht im Record enthalten sind. Normalerweise würde ich den bisherigen Record einfach erweitern. Das geht jedoch nicht da der Record an bestimmten Stellen auch in eine Datei geschrieben wird bzw. daraus gelesen wird.
Um nicht überall den Quelltext ändern zu müssen und die bisherigen Recordfunktionen kopieren zu müssen etc. würde ich somit gern vom bisherigen Record ableiten.

Bisher habe ich das so gelöst:
Delphi-Quellcode:
TMyNewRecord = record
  Base: TRecordBase;
  extraData: Byte;
end;
Das hat jedoch den Nachteil das man die Stellen wo bisher "baseRecord.ValueXY := ..." verwendet wurde, ändern muss zu "baseRecord.Base.ValueXY := ..."

Das ganze auf Objekte umzustellen ist in dem Fall keine Lösung (also bitte diesen Lösungsvorschlag vergessen).

mleyen 6. Dez 2010 09:37

AW: Ableiten von Records
 
Afaik gibt es keinen sauberen Weg.
Entweder man macht es so wie du (immer weiter das abzuleitende Record als seperate Eigenschaft kapseln) oder man macht eine Klasse draus.

himitsu 6. Dez 2010 09:38

AW: Ableiten von Records
 
Records bieten keine Vererbung, wengleich sowas bestimmt cool gewesen wäre.
(also eingebettete Records zumindestens)

also dein bisheriger Weg wäre so das allgemein anerkannte Vorgehen.

himitsu 6. Dez 2010 09:41

AW: Ableiten von Records
 
Zitat:

Zitat von mleyen (Beitrag 1066459)
Afaik gibt es keinen sauberen Weg.
Entweder man macht es so wie du (immer weiter das 'abzuleitende' Record als seperate Eigenschaft kapseln) oder man macht eine Klasse draus.

Andersfalls bleiben nur noch Redefinierungen und dann Zeigerfummeleien.


Seit 2006 könnte man aber auch noch sowas machen:
Delphi-Quellcode:
TRecordBase = record
  Feld1: Integer;
  Feld2: String;
end;
TMyNewRecord = record
private
  function GetFeld1: Integer; inline;
  ...
public
  Base: TRecordBase;
  extraData: Byte;
  property Feld1: Integer read GetFeld1 write SetFeld1;
end;

function TMyNewRecord.GetFeld1: Integer;
begin
  Result := Base.Feld1;
end;

SirThornberry 6. Dez 2010 09:42

AW: Ableiten von Records
 
Es muss auch nicht unbedingt Vererbung im eigentlichen Sinne sein.
Mir wäre auch so etwas ganz recht:
Delphi-Quellcode:
TBaseRecord = record
{$CONTENT01}
  Value: Byte;
{$ENDCONTENT}
end;

TNewRecord = record
{$I $CONTENT01}
end;
Das dies geht wenn man den Record-Inhalt in externe Dateien auslagert ist mir klar aber geht das auch in einer Datei das man einen Quellcodeabschnitt später wieder verwenden kann?

Mir geht es hauptsächlich darum nicht an Zig stellen alles ändern zu müssen sondern mir wäre es ganz recht wenn ich nur die Declaration ändern muss.

himitsu 6. Dez 2010 09:48

AW: Ableiten von Records
 
Delphi-Quellcode:
TBaseRecord = record
  Value: Byte;
end;

TNewRecord = record(TBaseRecord)
  Value2: Integer;
end;

// welches dann dieses gergibt (neue Werte hinten angehängt)
TNewRecord = record(TBaseRecord)
  Value: Byte;
  Value2: Integer;
end;
oder vielleicht in etwa sowas, wo man dann namenlos einen Record irgendwo einfügen kann.
Delphi-Quellcode:
TBaseRecord = record
  Value: Byte;
end;

TNewRecord = record(TBaseRecord)
  Value2: Integer;
  *:     TBaseRecord;
  Value3: Integer;
end;
Von der Syntax her wäre Beides kein Problem und bestimmt nichmal all zu schwer implementierbar.

generic 6. Dez 2010 10:24

AW: Ableiten von Records
 
Zitat:

Zitat von SirThornberry (Beitrag 1066455)
Bisher habe ich das so gelöst:
Delphi-Quellcode:
TMyNewRecord = record
  Base: TRecordBase;
  extraData: Byte;
end;
Das hat jedoch den Nachteil das man die Stellen wo bisher "baseRecord.ValueXY := ..." verwendet wurde, ändern muss zu "baseRecord.Base.ValueXY := ..."

Du kannst den Zeiger von TMyNewRecord auf TRecordBase casten.
Somit entfällt das ".Base." - aber du verlierst auch den Zugriff auf die neuen Felder.

SirThornberry 6. Dez 2010 10:29

AW: Ableiten von Records
 
Genau, so ähnlich mache ich es jetzt auch (bis es eine bessere Lösung gibt). Aber mir wäre es lieber mit weniger Quelltextänderungen das ganze hin zu bekommen.

uligerhardt 6. Dez 2010 11:25

AW: Ableiten von Records
 
Zitat:

Zitat von himitsu (Beitrag 1066462)
Seit 2006 könnte man aber auch noch sowas machen:
Delphi-Quellcode:
TRecordBase = record
  Feld1: Integer;
  Feld2: String;
end;
TMyNewRecord = record
private
  function GetFeld1: Integer; inline;
  ...
public
  Base: TRecordBase;
  extraData: Byte;
  property Feld1: Integer read GetFeld1 write SetFeld1;
end;

function TMyNewRecord.GetFeld1: Integer;
begin
  Result := Base.Feld1;
end;

Das geht sogar noch wesentlich einfacher:
Delphi-Quellcode:
type
  TRecordBase = record
    Feld1: Integer;
    Feld2: string;
  end;

  TMyNewRecord = record
  public
    Base: TRecordBase;
    extraData: Byte;
    property Feld1: Integer read Base.Feld1 write Base.Feld1;
  end;

SirThornberry 6. Dez 2010 11:38

AW: Ableiten von Records
 
Das bringt mich nur kein Stückchen Weiter.
Dann müsste ich ja für jedes Feld in meinem Record (sind etwa 30 Stück) ein Property definieren.
Und wenn ich irgendwann von TMyNewRecord auf diese Art "ableite" bezweifle ich das er dann auf eben die gleiche Weise auf Feld1 von Base zugreifen würde:

Delphi-Quellcode:
 TRecordBase = record
    Feld1: Integer;
    Feld2: string;
  end;

  TMyNewRecord = record
  public
    Base: TRecordBase;
    extraData: Byte;
    property Feld1: Integer read Base.Feld1 write Base.Feld1;
  end;

  TMyNewRecordV2 = record
  public
    Base: TMyNewRecord;
    extraData2: Byte;
    property Feld1: Integer read Base.Feld1 write Base.Feld1; // <== funktioniert nicht da bei read und write Felder erwartet werden
  end;

himitsu 6. Dez 2010 11:59

AW: Ableiten von Records
 
Delphi-Quellcode:
property Feld1: Integer read Base.Base.Feld1 write Base.Base.Feld1;
.
hatte sowas auch mal versucht und bei mir ging es damals irgendwie auch nicht.
(nja, die letzen Male, wo ich sowas gätte gebrauchen können, da hab ich eh intervaces genutzt, wo sowieso keine Zugriffe auf Felde möglich sind)

PS: Das Inline optimiert den Getter/Setter eh weg. (also bei einem Objekt)

uligerhardt 6. Dez 2010 12:00

AW: Ableiten von Records
 
Zitat:

Zitat von SirThornberry (Beitrag 1066542)
Das bringt mich nur kein Stückchen Weiter.
Dann müsste ich ja für jedes Feld in meinem Record (sind etwa 30 Stück) ein Property definieren.

Es ist immerhin eine Lösung, die man an einer zentralen Stelle implementieren kann, statt quer durch den ganzen Quellcode zu gehen und Casts einzubauen :mrgreen:. Und mit etwas Makrotrickserei ist das auch kein Riesenaufwand.

uligerhardt 6. Dez 2010 12:05

AW: Ableiten von Records
 
Zitat:

Zitat von himitsu (Beitrag 1066545)
Delphi-Quellcode:
property Feld1: Integer read Base.Base.Feld1 write Base.Base.Feld1;
.
hatte sowas auch mal versucht und bei mir ging es damals irgendwie auch nicht.

Also, das compiliert:
Delphi-Quellcode:
  TRecordBase = record
    Feld1: Integer;
    Feld2: string;
  end;

  TMyNewRecord = record
  public
    Base: TRecordBase;
    extraData: Byte;
    property Feld1: Integer read Base.Feld1 write Base.Feld1;
  end;

  TMyNewRecord2 = record
  public
    Base: TMyNewRecord;
    extraData: Byte;
    property Feld1: Integer read Base.Base.Feld1 write Base.Base.Feld1;
  end;
Ob's auch in komplizierteren Fällen compiliert und vor allem auch funktioniert, hab ich jetzt nicht ausprobiert. :mrgreen:

Zitat:

Zitat von himitsu (Beitrag 1066545)
PS: Das Inline optimiert den Getter/Setter eh weg. (also bei einem Objekt)

OK. Aber schreiben musste das Ding trotzdem. ;-)

himitsu 6. Dez 2010 12:16

AW: Ableiten von Records
 
Zitat:

Zitat von uligerhardt (Beitrag 1066548)
OK. Aber schreiben musste das Ding trotzdem. ;-)

Autovervollständigung, Copy&Paste und nach 'ner Weile schreibt man sowas blind in wenigen Sekunden dahin. :stupid:

pustekuchen 25. Okt 2013 08:03

AW: Ableiten von Records
 
Hallo,

*thread ausgrab*

gab es Verbesserungen in den letzten Delphi bezüglich der Vererbung von Records?

Stevie 25. Okt 2013 08:18

AW: Ableiten von Records
 
Ich würde mal sagen, das ist nach wie vor ein Fall für old style objects.

MacGuyver 12. Nov 2015 13:50

AW: Ableiten von Records
 
Moin Leute :hi:

Entschuldigt, dass ich diesen alten Bug wieder ausgrabe. Ich habe das Thema für meine DLL-Schnittstelle benötigt. Meine Lösung:

Eine Include-Datei (DLLdef.inc):
Delphi-Quellcode:
{$IFDEF Ver1}
  a : Byte;
  b : AnsiString;
{$ENDIF}

{$IFDEF Ver2}
  c : Byte;
  d : AnsiString;
{$ENDIF}

{$IFDEF Ver3}
  e : Byte;
  f : AnsiString;
{$ENDIF}
Und den Code in der Unit:
Delphi-Quellcode:
type
{$DEFINE Ver1}
  TVer1 = packed record
  {$INCLUDE DLLdef.inc}
  end;

{$DEFINE Ver2}
  TVer2 = packed record
  {$INCLUDE DLLdef.inc}
  end;

{$DEFINE Ver3}
  TVer3 = packed record
  {$INCLUDE DLLdef.inc}
  end;
Im Code verhält sich das dann wie erwartet.

Mavarik 12. Nov 2015 16:33

AW: Ableiten von Records
 
Wenn Du statische Include machst... Kannst Du den code auch direkt da hin schreiben...

Das hat nix mit Vererbung zu tun...

MacGuyver 27. Jan 2016 12:42

AW: Ableiten von Records
 
Es hat einen großen Vorteil. Wenn du einen Typen mit 50 Variablen hast und fügst eine an, darf beim Kopieren nichts falsch laufen. Ist da ein Fehler in einer Zwischenversion, suchst du dir 'nen Wolf. Wenn du mit mehreren Include-Datei arbeitest, kannst du sogar eine Hirarchie aufbauen.

Ich weiß, dass es hier keine Vererbung gibt!


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:06 Uhr.

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