



Esta é uma forma de realmente clonar um objeto, fazer uma cópia e modificar a cópia
sem afetar o objeto original.
Também podemos chamar de cópia profunda ou Deep copying.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | //..... uses DBXJSON, DBXJSONReflect; //..... function DeepCopy(aValue: TObject): TObject; var MarshalObj: TJSONMarshal; UnMarshalObj: TJSONUnMarshal; JSONValue: TJSONValue; begin Result:= nil; MarshalObj := TJSONMarshal.Create; UnMarshalObj := TJSONUnMarshal.Create; try JSONValue := MarshalObj.Marshal(aValue); try if Assigned(JSONValue) then Result:= UnMarshalObj.Unmarshal(JSONValue); finally JSONValue.Free; end; finally MarshalObj.Free; UnMarshalObj.Free; end; end; |
Exemplo de como utilizar
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | //..... var MyObject1, MyObject2: TMyObject; begin //Regular object construction MyObject1:= TMyObject.Create; //Deep copying an object MyObject2:= TMyObject(DeepCopy(MyObject1)); try //Fazer alogo aqui finally MyObject1.Free; MyObject2.Free; end; end; |
A princípio esta ideia deve funcionar em todos casos, inclusive com objetos complexos.
Mas isso não é tudo, que tal estender este função para todos os objetos? Sim é possível, desde que utilizamos helpers.
Veja o exemplo abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | //..... interface uses DBXJSON, DBXJSONReflect; type TObjectHelper = class helper for TObject function Clone: TObject; end; implementation function TObjectHelper.Clone: TObject; var MarshalObj: TJSONMarshal; UnMarshalObj: TJSONUnMarshal; JSONValue: TJSONValue; begin Result:= nil; MarshalObj := TJSONMarshal.Create; UnMarshalObj := TJSONUnMarshal.Create; try JSONValue := MarshalObj.Marshal(Self); try if Assigned(JSONValue) then Result:= UnMarshalObj.Unmarshal(JSONValue); finally JSONValue.Free; end; finally MarshalObj.Free; UnMarshalObj.Free; end; end; |
Todos descendente de TObject irão possuir o método Clone! Que pode ser chamado deste modo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | //..... var MyObject1, MyObject2: TMyObject; begin //Regular object construction MyObject1:= TMyObject.Create; //Cloning an object MyObject2:= TMyObject(MyObject1.Clone); try //Do something here finally MyObject1.Free; MyObject2.Free; end; end; |
Fonte de Referência: http://www.yanniel.info/2012/02/deep-copy-clone-object-delphi.html