Como funciona a Interface ICloneable, do .NET ?


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