另一种解决方案是使用辅助函数:
procedure SetValue(i: Integer; const Value: Integer);
begin
i := Value;
end;
SetValue(MyClass.Rec.Member, 10);
虽然还不够安全(请参阅Barry Kelly有关Getter/Setter的评论)
/编辑:以下是最丑陋的黑客攻击方式(可能也是最不安全的),但它非常有趣,我必须发布:
type
TRec = record
Member : Integer;
Member2 : Integer;
end;
TMyClass = class
private
FRec : TRec;
function GetRecByPointer(Index: Integer): Integer;
procedure SetRecByPointer(Index: Integer; const Value: Integer);
public
property Rec : TRec read FRec write FRec;
property RecByPointer[Index: Integer] : Integer read GetRecByPointer write SetRecByPointer;
end;
function TMyClass.GetRecByPointer(Index: Integer): Integer;
begin
Result := PInteger(Integer(@FRec) + Index * sizeof(PInteger))^;
end;
procedure TMyClass.SetRecByPointer(Index: Integer; const Value: Integer);
begin
PInteger(Integer(@FRec) + Index * sizeof(PInteger))^ := Value;
end;
它假设记录的每个成员都是(P)Integer大小的,如果不是,将会崩溃。
MyClass.RecByPointer[0] := 10; // Set Member
MyClass.RecByPointer[1] := 11; // Set Member2
你甚至可以将偏移量硬编码为常量,并通过偏移量直接访问
const
Member = 0;
Member2 = Member + sizeof(Integer);
MyClass.RecByPointer[Member] := 10;
function TMyClass.GetRecByPointer(Index: Integer): Integer;
begin
Result := PInteger(Integer(@FRec) + Index)^;
end;
procedure TMyClass.SetRecByPointer(Index: Integer; const Value: Integer);
begin
PInteger(Integer(@FRec) + Index)^ := Value;
end;
MyClass.RecByPointer[Member1] := 20;
TRec
是一个类,它就可以工作。因此,这里有两个重要的事实(它是一个值类型和它通过属性访问)。 - jpfolleniuswith
,我希望尽量减少代码更改。 - jpfollenius