Einzelnen Beitrag anzeigen

Benutzerbild von Stevie
Stevie

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

AW: Record Property verschachtelt - Schreibzugriff

  Alt 30. Mär 2021, 10:32
Geht auch mehrfach verschachtelt:
Delphi-Quellcode:
  TTestObj1 = class( TObject)
  private
    FTest2: TTestRec2;
  public
    property IntValue: Integer read FTest2.Test1.IntValue write FTest2.Test1.IntValue;
  end;

...

var
  ltest: TTestObj1;
begin
  ltest := TTestObj1.Create;
  ltest.IntValue := 10;
end;


Zum Problem an sich haben die anderen ja schon was gesagt - der Kern ist hier die API - die definiert hier eine Eigenschaft eines Wertetypens, und auch wenn der Zugriff auf ein Feld ohne Getter durch den Compiler letztlich im Binärcode als direkter Speicherzugriff implementiert wird und es auch einige Schlupflöcher(*) gibt, wird hier sichergestellt, dass man durch das direkte Zuweisen des Feldes auf das, was eine Kopie sein könnte nicht passiert.

(*)
1. Durch das Hinzufügen von Methoden zu Recordtypen wurde das ganze ein bisschen kompliziert gemacht - Beispiel:

Delphi-Quellcode:
type
  TTestRec = record
  public
    IntValue: Integer;
    procedure SetValue(i: Integer);
  end;

  TTestObj = class
  private
    FTest: TTestRec;
    function GetTest2: TTestRec;
  public
    property Test: TTestRec read FTest;
    property Test2: TTestRec read GetTest2;
  end;

procedure TTestRec.SetValue(i: Integer);
begin
  IntValue := i;
end;

function TTestObj.GetTest2: TTestRec;
begin
  Result := FTest;
end;

procedure Test;
var
  t: TTestObj;
begin
  t := TTestObj.Create;
  t.Test.SetValue(10);
  t.Test2.SetValue(20);
  Writeln(t.Test.IntValue); // was kommt raus? Spoiler: 10
end;
2. Wenn Eigenschaften direkt auf ein Feld gehen, kann man mit @ auf die Addresse "durchgreifen":

Delphi-Quellcode:
procedure SetValue(val: PInteger; i: Integer);
begin
  val^ := i;
end;

...

procedure Test;
var
  t: TTestObj;
begin
  t := TTestObj.Create;
  SetValue(@t.Test.IntValue, 30); // funktioniert
  SetValue(@t.Test2.IntValue, 40); // funktioniert nicht - compilefehler E2036 Variable required
end;
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight

Geändert von Stevie (30. Mär 2021 um 10:48 Uhr)
  Mit Zitat antworten Zitat