AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi privaten Record über Getter heraus geben
Thema durchsuchen
Ansicht
Themen-Optionen

privaten Record über Getter heraus geben

Ein Thema von stahli · begonnen am 28. Jul 2016 · letzter Beitrag vom 1. Aug 2016
Antwort Antwort
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#1

privaten Record über Getter heraus geben

  Alt 28. Jul 2016, 23:36
Delphi-Version: XE3
Ich hatte eigentlich gerade ein komplexes Problem beschrieben, konnte das aber jetzt kürzen.
(Testprojekt und Video von der ursprünglichen Frage könnte ich bei Interesse nachliefern)

Also im Kern ergibt sich folgendes:

Ich habe einen Record
Delphi-Quellcode:
  PGuid = ^TGuid;
  TGuid = record
  private
    fTS1: TDateTime;
    fTS2: TDateTime;
    fC: LongWord;
    ....
  public
    ....
    property AsString: String read get_AsString write set_AsString;
und Interfaces bzw. Klassen, die diesen als Eigenschaft benutzen:
Delphi-Quellcode:
  IGuidObj = interface
    ['{4E5492DE-D248-40C8-8AED-EF9819C32FD6}']
    function _get_Guid: TGuid;
    procedure _set_Guid(const aGuid: TGuid);
    property Guid: TGuid read _get_Guid write _set_Guid;
  end;

  TGuidObj = class(TInterfacedObject, IGuidObj)
  protected
    fGuid: TGuid;
    function _get_Guid: TGuid;
    procedure _set_Guid(const aGuid: TGuid);
  public
    constructor Create; overload; virtual;
    constructor Create(aGuid: TGuid); reintroduce; overload; virtual;
    destructor Destroy; override;
    property Guid: TGuid read _get_Guid write _set_Guid;
  end;

Das Problem ist, dass der Getter jetzt eine KOPIE des Records heraus gibt und ich so nicht direkt in das private Feld schreiben kann.
Delphi-Quellcode:
function TGuidObj._get_Guid: TGuid;
begin
  Result := fGuid;
end;

Wie kann ich Result direkt auf fGuid zeigen lassen?
Ich kenne mich mit Pointern^ auf Records zu wenig aus...
Sollte doch aber sicher machbar sein - oder?
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

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

AW: privaten Record über Getter heraus geben

  Alt 29. Jul 2016, 06:30
Es genügt, wenn du die Property mit dem Typ PGuid deklarierst. Der Getter muss dann nur einen Pointer auf das private Feld vom Typ TGuid zurückliefern, also @FGuid statt FGuid.

Allerdings sind für den Zweck Klassen deutlich besser geeignet, da damit genau dieses Pointergehampel vermieden wird.

TGuid ist ein etwas unglücklicher Name für einen eigenen Typ, da Delphi selbst diesen Typ schon hat.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: privaten Record über Getter heraus geben

  Alt 29. Jul 2016, 14:06
Vielen Dank!

TGuid heißt mein Typ, weil ich im Projekt durchgängig die eigene Guid statt der System-Guid verwende (außer für die Interfaces). Da gibt es also keine Konflikte.

Records habe ich genutzt, weil ich gern die Klassenoperatoren nutzen wollte (habe XE3).

Ich werde wohl doch mal auf eine Klasse umstellen und für die Vergleiche Funktionen aufrufen.
Das scheint mir dann sauberer zu sein.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

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

AW: privaten Record über Getter heraus geben

  Alt 29. Jul 2016, 14:44
Mach deinen record halt immutable und erlaube nicht, einzelne Felder zu setzen.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: privaten Record über Getter heraus geben

  Alt 29. Jul 2016, 15:01
Oder eine Kombination aus Interface, Instanz und Record:
Delphi-Quellcode:
IFoo = interface
  function GetBar: Integer;
  procedure SetBar( const Value: Integer );
  property Bar : Integer read GetBar write SetBar;
end;

TFoo = record
private
  FFoo: IFoo;
  procedure EnsureInitialized();
  function GetBar: Integer;
  procedure SetBar( const Value: Integer );
public
  property Bar: Integer read GetBar write SetBar;
end;

TFooImpl = class( TInterfacedObject, IFoo )
private { IFoo }
  function GetBar: Integer;
  procedure SetBar( const Value: Integer );
private
  FBar: Integer;
end;

procedure TFoo.EnsureInitialized;
begin
  if not Assigned( FFoo )
  then
    FFoo := TFooImpl.Create;
end;

function TFoo.GetBar: Integer;
begin
  EnsureInitialized();
  Result := FFoo.Bar;
end;

procedure TFoo.SetBar( const Value: Integer );
begin
  EnsureInitialized();
  FFoo.Bar := Value;
end;

function TFooImpl.GetBar: Integer;
begin
  Result := FBar;
end;

procedure TFooImpl.SetBar( const Value: Integer );
begin
  FBar := Value;
end;
Dem Record sollte man dann aber noch eine Clone Methode spendieren, damit man bei Bedarf auch einen unabhängigen Record bekommen kann
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

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

AW: privaten Record über Getter heraus geben

  Alt 1. Aug 2016, 11:15
Das funktioniert leider nicht so einfach - du musst immernoch sicher stellen, dass das Interface innerhalb des Records vor dem herausgeben initialisiert ist.

Delphi-Quellcode:
type
  TQux = class
  private
    fFoo: TFoo;
  public
    property Foo: TFoo read fFoo;
  end;

...

var
  qux: TQux;
  foo: TFoo;
begin
  qux := TQux.Create;
  foo := qux.Foo;
  foo.Bar := 42;
  Assert(qux.Foo.Bar = 42); // whoops!
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: privaten Record über Getter heraus geben

  Alt 1. Aug 2016, 16:51
Danke Euch.

Ich nutze jetzt Interfaces (IsoGuid) und führe Vergleiche über Funktionen durch.

Die Umstellung war recht aufwendig aber ich denke, so geht es jetzt.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  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 07:51 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