Hi,
This started out as a PEBCAK problem.
I have a datastructure wich a.o. contains some dynamic arrays.
I pass that datstructure around to another class (as a property), change the copy, only to find out that the original was altered as well.
Just to explain what happened with some pseudo code:
Dlg := TDlg.Create;
Dlg.Options := GlobalOptions;
if Dlg.Execute then
begin
//at his point GlobalOptions had changed before I copied Dlg.Options back to GlobalOptions
//in fact this also happened if Execute returned false
...
GlobalOptions := Dlg.Options;
end;
(T.b.h. it took me some time to figure out that this "unexpected" behaviour only applied to the dynamic arrays, not to the other fields of the record.)
OK, I get why: the copy holds the pointer to the original dynamic array, the dynamic array contents are not copied.
So, I need to manually copy the contents to the destination.
To create a copy of the datastructure where actually the content of the dynamic array is copied, I can use OptionsCopy.DynamicArray := Copy(GlobalOptions.DynamicArray,Low(GlobalOptions.DynamicArray)).
So, I added a Assign() function to my datastructure (an advanced record).
The datstructure has many fields, the fast majority of them are not dynamic arrays.
I did not want to manually copy each and every field by hand (especially since the datastructure may get new fields in the future).
Here's basically how I implemented it:
type
TData = record
//some 20 odd fields of fixed records and strings
....
Files: Array[TFileType] of TFile; /TFileType is an enum, TFile is a dynamic array of some type that is not dynamical
procedure Assign(Src: TData);
end;
procedure TData.Assign(Src: TData);
var
FT: TFileType;
begin
Self := Src;
for FT := Low(TFileType) to High(TFileType) do
Self.Files[FT] := Copy(Src.Files[FT],Low(Src.Files[FT]));
end;
While this seems to work in fine in some limited tests I did, the question is: is this safe?
Especially the "Self := Src" bit inside the TData.Assign() procedure?
Bart