Question

I have an object that inherits in 3rd degree from TPersistent and I want to clone it using the Assign procedure.

MyFirstObj := GrandSonOfPersistent.Create();
//I modify the objects inside MyFirstObj
MySecondObj := GrandSonOfPersistent.Create();
MySecondObj.Assign(MyFirstObject);

How can I check it worked? Does it work when the objects have many other objects?

I am trying to clone an object, is this the correct way to do it?

Was it helpful?

Solution

Assign is a virtual method. Any descendent classes that inherit from TPersistent should override Assign to handle deep copying of any new members added on top of the base class. If your classes do not override Assign to handle these deep copies then using Assign to make such a copy will not be successful. The base implementation of Assign calls AssignTo which attempts to use the source object's implementation to perform the copy. If neither source nor destination object can handle the copy then an exception is raised.

See : The Documentation

For Example:

unit SomeUnit;

 interface

 uses Classes;

 type
   TMyPersistent = class(TPersistent)
   private
     FField: string;         
   public
     property Field: string read FField write FField;
     procedure Assign (APersistent: TPersistent) ; override;
   end;

 implementation

 procedure TMyPersistent.Assign(APersistent: TPersistent) ;
 begin        
    if APersistent is TMyPersistent then
      Field := TMyPersistent(APersistent).Field          
    else         
      inherited Assign (APersistent);
 end;

end. 

Note that any class inheriting from TPersistent should only call inherited if it cannot handle the Assign call. A descendent class, however, should always call inherited since the parent may also have actions to perform and, if not, will handle passing calling the base inherited :

type
  TMyOtherPersistent = class(TMyPersistent)
  private
    FField2: string;         
  public
    property Field2: string read FField2 write FField2;
    procedure Assign (APersistent: TPersistent) ; override;
  end;

implementation

procedure TMyPersistent.Assign(APersistent: TPersistent) ;
begin 
  if APersistent is TMyOtherPersistent then
    Field2 := TMyOtherPersistent(APersistent).Field2;     
  inherited Assign (APersistent);  
end;

In this example I've shown strings. For object members you would either need to use their Assign methods or perform the copy in some other way.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top