ICloneable
A
Interface ICloneable deve ser utilizada em classes que necessitem que
duplicatas. Os tipos por valor quando são atribuídos a outras variáveis, são
copiados; os tipos por referência são apenas apontados. Nos tipos por
referência não existem cópias ou duplicatas. Esta interface vem tentar resolver
este problema.
A
interface possui um método object clone() que retorna uma duplicada do objeto
em questão. O .NET nos auxilia na realização desta tarefa com um método chamado
object MemberwiseClone(). Este método somente pode ser acessado por dentro da
classe em quastão.
A
forma de criação do clone pode criar problemas em tempo de execução. Existem 2
tipos de clone: Shallow Copy e Deep Copy. Tomemos como exemplo a figura 1. Ela
apresenta uma classe chamada Objeto1 que possui um atributo chamado Objeto2.
Figura 1: Objeto possui um atributo, que é outro objeto |
Quando
se realiza a Shallow Copy, os objetos internos não são clonados. Isto pode ser
bastante desagradável. Utilize esta forma, somente, quando o objeto clonável
tiver apenas tipos por valor. As classes que herdarem desta classe clonável
devem ter implementações próprias do Clone(), caso contrário, as classes
herdeiras criarão clones da classe base.
Objeto clone continua apontando para o mesmo Objeto2, que é apontado também pelo Objeto 1 |
A forma Deep Copy realiza cópia dos objetos internos do objeto pai.
Para fazer isto, basta criar uma nova instancia da classe clonável no clone(),
com todos os objetos chamando seus próprios clones. Esta tarefa pode ser
tediosa, mas importante para evitar duplicatas. Todos os atributos da classe
clonável devem implementar ICloneable ou serem passíveis de duplicação manual.
Objeto 1 e Objeto 2 são totalmente clonados |
Exemplo:
public
class Pessoa:
ICloneable
{
String
nome;
Int32
idade;
Telefone
telefone;
public
Pessoa(String nome, Int32
idade, Telefone telefone)
{
this.nome
= nome;
this.idade
= idade;
this.telefone = telefone;
}
#region ICloneable Members
public object Clone()
{
//
Shallow Copy
//return
this.MemberwiseClone();
// Deep
Copy
return
new Pessoa(this.nome, this.idade,
new Telefone(this.Telefone.Numero));
}
#endregion
}
Nenhum comentário:
Postar um comentário