![]() |
Delphi-Version: XE3
privaten Record über Getter heraus geben
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:
und Interfaces bzw. Klassen, die diesen als Eigenschaft benutzen:
PGuid = ^TGuid;
TGuid = record private fTS1: TDateTime; fTS2: TDateTime; fC: LongWord; .... public .... property AsString: String read get_AsString write set_AsString;
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? ;-) |
AW: privaten Record über Getter heraus geben
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. |
AW: privaten Record über Getter heraus geben
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. |
AW: privaten Record über Getter heraus geben
Mach deinen record halt immutable und erlaube nicht, einzelne Felder zu setzen.
|
AW: privaten Record über Getter heraus geben
Oder eine Kombination aus Interface, Instanz und Record:
Delphi-Quellcode:
Dem Record sollte man dann aber noch eine Clone Methode spendieren, damit man bei Bedarf auch einen unabhängigen Record bekommen kann :stupid:
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; |
AW: privaten Record über Getter heraus geben
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! |
AW: privaten Record über Getter heraus geben
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. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:21 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