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;