Maneira correta de duplicar o objeto Delphi
Quais são os prós e os contras da duplicação de uma instância de objeto com construtor ou função de instância?
Exemplo A:
type
TMyObject = class
strict private
FField: integer;
public
constructor Create(srcObj: TMyObject); overload;
//alternatively:
//constructor CreateFrom(srcObj: TMyObject);
property Field: integer read FField;
end;
constructor TMyObject.Create(srcObj: TMyObject);
begin
inherited Create;
FField := srcObj.Field;
end;
Exemplo B:
type
TMyObject = class
strict private
FField: integer;
public
function Clone: TMyObject;
property Field: integer read FField;
end;
function TMyObject.Clone: TMyObject;
begin
Result := TMyObject.Create;
Result.FField := FField;
end;
Uma grande diferença imediatamente vem à mente - no último caso, o construtor Create precisaria ser virtual para que uma hierarquia de classes que suporta o Clone pudesse ser construída com base no TMyObject.
Suponha que isso não seja um problema - que o TMyObject e tudo baseado nele estejam inteiramente sob meu controle. Qual é a sua maneira preferida de fazer um construtor de cópias no Delphi? Qual versão você acha mais legível? Quando você usaria a abordagem anterior ou posterior? Discutir. :)
EDIT: Minha principal preocupação com o primeiro exemplo é que o uso é muito pesado comparado à segunda abordagem, ou seja,
newObj := TMyObject.Create(oldObj)
vs.
newObj := oldObj.Clone;
EDIT2 ou "Por que eu quero operação em linha única"
Concordo que a atribuição é uma abordagem razoável na maioria dos casos. É até razoável implementar o 'construtor de cópias' internamente, simplesmente usando o atributo
Normalmente, estou criando essas cópias ao multithreading e ao passar objetos pela fila de mensagens. Se a criação do objeto é rápida, geralmente passo uma cópia do objeto original, porque isso realmente simplifica os problemas de propriedade do objeto.
Eu prefiro escrever
Send(TMyObject.Create(obj));
ou
Send(obj.Clone);
para
newObj := TMyObject.Create;
newObj.Assign(obj);
Send(newObj);