Delphi中如何让返回的内部Record可直接修改?
解决Delphi记录AddChild方法返回值直接修改的问题
问题根源
Delphi中的记录是值类型,默认以值传递/返回:
- 若AddChild返回记录实例,实际返回的是原数组元素的副本,这个临时副本属于"右值",编译器不允许直接修改;
- 若返回指针,函数返回的临时指针是不可寻址的临时值,
with语句无法直接识别,必须先赋值给变量才能使用。
可行解决方案
方案1:返回指针并配合解引用使用with
修改AddChild方法,让它返回新增子记录的指针(^TDatasetInfo类型),调用时通过^解引用指针,直接操作原数组中的元素:
type TDatasetInfo = record Children: array of TDatasetInfo; CascadeDeletes: Boolean; function AddChild(...): ^TDatasetInfo; end; function TDatasetInfo.AddChild(...): ^TDatasetInfo; begin SetLength(Children, Length(Children) + 1); // 初始化新增子记录的默认属性 Children[High(Children)].CascadeDeletes := True; // 示例默认值 Result := @Children[High(Children)]; end; // 调用方式 with ADatasetInfo.AddChild(...)^ do CascadeDeletes := False;
方案2:将TDatasetInfo改为类(推荐)
把记录换成类(引用类型),类实例默认以引用传递,AddChild返回的就是新增实例的引用,直接用with即可修改原实例属性,完全符合你想要的写法:
type TDatasetInfo = class public Children: array of TDatasetInfo; CascadeDeletes: Boolean; constructor Create; function AddChild(...): TDatasetInfo; end; constructor TDatasetInfo.Create; begin inherited; CascadeDeletes := True; // 示例默认值 end; function TDatasetInfo.AddChild(...): TDatasetInfo; begin Result := TDatasetInfo.Create; SetLength(Children, Length(Children) + 1); Children[High(Children)] := Result; end; // 调用方式 with ADatasetInfo.AddChild(...) do CascadeDeletes := False;
方案3:使用带指针输出参数的过程
如果不想修改现有记录结构,可将AddChild改为过程,通过out参数返回新增子记录的指针,再用with修改:
type TDatasetInfo = record Children: array of TDatasetInfo; CascadeDeletes: Boolean; procedure AddChild(out ChildPtr: ^TDatasetInfo); end; procedure TDatasetInfo.AddChild(out ChildPtr: ^TDatasetInfo); begin SetLength(Children, Length(Children) + 1); Children[High(Children)].CascadeDeletes := True; // 示例默认值 ChildPtr := @Children[High(Children)]; end; // 调用方式 var NewChild: ^TDatasetInfo; begin ADatasetInfo.AddChild(NewChild); with NewChild^ do CascadeDeletes := False; end;
内容的提问来源于stack exchange,提问作者Marc Guillot
相关产品推荐
相关产品推荐

