none
Desfazer alterações objetos RRS feed

  • Pergunta

  • Pessoal !

    Por favor tenho a seguinte duvida... tem como controlar as alterações de um objeto instanciado e se necessário desfazer as alterações... comparando com as transações do banco de dados utilizando o TransactionScope

    Exemplo:

    Objeto obj = New Objeto();

    obj.valor1 = 1;

    obj.valor2 = 2;

    TRY

    {

      calcular();

    }

    CATCH (Exception e)

    {

       /// Preciso voltar o estado do objeto obj antes do Try



    }

    No exemplo acima se der qualquer erro preciso voltar o resultado obj antes de entrar no try

    Desde já sou muito grato

    Jairo

    quarta-feira, 30 de janeiro de 2013 14:57

Todas as Respostas

  • Fala Jairo, acredito que não há apenas uma solução, mas criei uma interessante. Sabemos que as classes são do tipo por referência, então se quisermos fazer uma "cópia" de uma para outra ela não copiará o valor, copiará apenas a referência para a memória, mas como podemos copiar para outra referência da memória?

    Você pode fazer isso implementando a interface ICloneable em sua classe, no meu exemplo eu crio uma classe chamada "Produto" e implemento ICloneable:

    public class Produto : ICloneable
    {
        public int Valor1 { get; set; }
        public int Valor2 { get; set; }
    
        public object Clone()
        {
            return this.MemberwiseClone();
        }
    }

    Pode ver que o método Clone está implementado, ele será responsável por clonar nossa classe apra outra referência da memória.

    Agora para testarmos, eu criei uma Console Application, onde eu guardo o produto original em uma classe "clonada" e depois aponto o produto original para ela em caso de erro:

    static void Main(string[] args)
    {
        Produto prod = new Produto();
        prod.Valor1 = 5;
        prod.Valor2 = 10;
        //Valores atuais
        Console.WriteLine(prod.Valor1);
        Console.WriteLine(prod.Valor2);
    
        //Classe clonada
        Produto prodClonado = (Produto)prod.Clone();
    
        try
        {
            prod.Valor1 = 100;
            prod.Valor2 = 200;
            //valores trocados
            Console.WriteLine(prod.Valor1);
            Console.WriteLine(prod.Valor2);
    
            //forçando exceção
            int a = Convert.ToInt32("AAA");         
        }
        catch (Exception)
        {
            //voltando ao produto através de nossa cópia clonada
            prod = prodClonado;
    
            //valores idênticos aos originais
            Console.WriteLine(prod.Valor1);
            Console.WriteLine(prod.Valor2);
        }
    
        Console.Read();
    }

    Espero ter te ajudado, qualquer dúvida dá um toque.

    Abraços!


    Thiago Coelho - Líder das Comunidades .NET Coders e Windows 8 Brasil
    thiagocoelho.net | @thiagokoelho

    quarta-feira, 30 de janeiro de 2013 15:40
  • Jairo,

    Você pode usar da interface ICloneable e implementar o método Clone, customizando um propriedade que  guardara neste próprio objeto o seu estado anterior antes da alterações:

    using System;
    
    namespace ConsoleApplication3
    {
        public class Program
        {
    
            public class MeuObjeto : ICloneable
            {
                public int Valor1 { get; set; }
                public int Valor2 { get; set; }
    
                private MeuObjeto MeuObjetoOriginal { get; set; }
    
                public object Clone()
                {
                    var clone = this.MemberwiseClone();
    
                    if (clone != null)
                        this.MeuObjetoOriginal = (MeuObjeto)clone;
    
                    return clone;
                }
    
                public void RestauraMeuObjeto()
                {
                    if (MeuObjetoOriginal != null)
                    {
                        this.Valor1 = MeuObjetoOriginal.Valor1;
                        this.Valor2 = MeuObjetoOriginal.Valor2;
                    }
                }
            }
    
    
            static void Main(string[] args)
            {
                MeuObjeto b = new MeuObjeto();
    
                b.Valor1 = 1;
                b.Valor2 = 2;
    
                Console.WriteLine(b.Valor1);
                Console.WriteLine(b.Valor2);
    
                b.Clone();
    
                try
                {
                    Console.WriteLine("Entrei na rotina sujeita a excessão");
    
                    b.Valor1 = 2000;
                    b.Valor2 = 1000;
    
                    Console.WriteLine(b.Valor1);
                    Console.WriteLine(b.Valor2);
    
                    Console.WriteLine("Lançando excessão");
    
                    throw new Exception();
    
                }
                catch (Exception)
                {
                    Console.WriteLine("Rollback no objeto");
    
                    b.RestauraMeuObjeto();
                }
    
                Console.WriteLine(b.Valor1);
                Console.WriteLine(b.Valor2);
            }
        }
    }
    


    Vitor Mendes | Seu feedback é muito importante para todos!
    Visite o meu site: http://www.vitormendes.com.br/

    quarta-feira, 30 de janeiro de 2013 15:51