读写 属性 类型记录
read write property of type record
声明 属性 类型记录有什么缺点吗?
TMyObject = class(TObject)
private
FSomeRecord: TMyRecord;
public
property SomeRecord: TMyRecord read FSomeRecord write FSomeRecord;
end;
指令 Myobject.SomeRecord.xxx := yyy
如何在后台工作(我认为这实际上行不通)?
如果不行,记录属性怎么办?避免它并像下面这样声明 TMyobject 是否更好?
TMyObject = class(TObject)
public
SomeRecord: TMyRecord;
end;
你说得对 Myobject.SomeRecord.xxx := yyy
不会按你想要的方式工作。它将调用 属性 getter,返回记录的 copy,然后您将更新副本的 xxx
字段,而不是原本的。本质上,生成的代码将像这样:
var tmp: TMyRecord;
tmp = Myobject.FSomeRecord;
tmp.xxx := yyy;
除非您需要 属性 的 RTTI,否则没有充分的理由声明只直接访问字段的读+写 属性。只需公开 public 对该字段的访问权限即可。
避免这种情况的一种方法是将 属性 声明为指向记录的指针(如果您只需要访问 fields/methods 中的 记录):
TYPE
TMyRecord = RECORD
Field1 : INTEGER;
END;
PMyRecord = ^TMyRecord;
TYPE
TMyClass = CLASS
PRIVATE
FMyRecord : TMyRecord;
FUNCTION GetRec : PMyRecord;
PUBLIC
PROPERTY MyRec : PMyRecord Read GetRec;
END;
{ TMyClass }
FUNCTION TMyClass.GetRec : PMyRecord;
BEGIN
Result:=@FMyRecord
END;
.
.
.
VAR
MC : TMyClass;
.
.
.
MC.MyRec.Field1:=12
.
.
.
由于“扩展语法”,您可以short-circuit使用
的正常语法
MC.MyRec^.Field1:=12
到
MC.MyRec.Field1:=12
但不能用于以下用途:
VAR NewRec : TMyRecord := MC.MyRec;
必须编码为
VAR NewRec : TMyRecord := MC.MyRec^;
除非您为 PMyRecord 引入一个 RECORD HELPER,它实现了对 TMyRecord 的隐式转换:
TYPE
PMyRecHelper = RECORD HELPER FOR PMyRecord
CLASS OPERATOR Implicit(P : PMyRecord) : TMyRecord;
END;
{ PMyRecHelper }
CLASS OPERATOR PMyRecHelper.Implicit(P : PMyRecord) : TMyRecord;
BEGIN
Result:=P^
END;
不幸的是,上面的代码在编译时不起作用。 Delphi 不允许在记录助手中使用运算符重载...
因此,在实施最后一项之前,您只有 semi-working 实施...
声明 属性 类型记录有什么缺点吗?
TMyObject = class(TObject)
private
FSomeRecord: TMyRecord;
public
property SomeRecord: TMyRecord read FSomeRecord write FSomeRecord;
end;
指令 Myobject.SomeRecord.xxx := yyy
如何在后台工作(我认为这实际上行不通)?
如果不行,记录属性怎么办?避免它并像下面这样声明 TMyobject 是否更好?
TMyObject = class(TObject)
public
SomeRecord: TMyRecord;
end;
你说得对 Myobject.SomeRecord.xxx := yyy
不会按你想要的方式工作。它将调用 属性 getter,返回记录的 copy,然后您将更新副本的 xxx
字段,而不是原本的。本质上,生成的代码将像这样:
var tmp: TMyRecord;
tmp = Myobject.FSomeRecord;
tmp.xxx := yyy;
除非您需要 属性 的 RTTI,否则没有充分的理由声明只直接访问字段的读+写 属性。只需公开 public 对该字段的访问权限即可。
避免这种情况的一种方法是将 属性 声明为指向记录的指针(如果您只需要访问 fields/methods 中的 记录):
TYPE
TMyRecord = RECORD
Field1 : INTEGER;
END;
PMyRecord = ^TMyRecord;
TYPE
TMyClass = CLASS
PRIVATE
FMyRecord : TMyRecord;
FUNCTION GetRec : PMyRecord;
PUBLIC
PROPERTY MyRec : PMyRecord Read GetRec;
END;
{ TMyClass }
FUNCTION TMyClass.GetRec : PMyRecord;
BEGIN
Result:=@FMyRecord
END;
.
.
.
VAR
MC : TMyClass;
.
.
.
MC.MyRec.Field1:=12
.
.
.
由于“扩展语法”,您可以short-circuit使用
的正常语法MC.MyRec^.Field1:=12
到
MC.MyRec.Field1:=12
但不能用于以下用途:
VAR NewRec : TMyRecord := MC.MyRec;
必须编码为
VAR NewRec : TMyRecord := MC.MyRec^;
除非您为 PMyRecord 引入一个 RECORD HELPER,它实现了对 TMyRecord 的隐式转换:
TYPE
PMyRecHelper = RECORD HELPER FOR PMyRecord
CLASS OPERATOR Implicit(P : PMyRecord) : TMyRecord;
END;
{ PMyRecHelper }
CLASS OPERATOR PMyRecHelper.Implicit(P : PMyRecord) : TMyRecord;
BEGIN
Result:=P^
END;
不幸的是,上面的代码在编译时不起作用。 Delphi 不允许在记录助手中使用运算符重载...
因此,在实施最后一项之前,您只有 semi-working 实施...