Muitas aplicações necessitam de armazenar ou transferir objetos. Para fazer as tarefas simples o possível, o .NET Framework inclui muitas técnicas de serialização. As técnicas para converter objetos em binário, SOAP, ou documentos XML (Extensible Markup Language) que podem ser facilmente armazenados, transferidos e recuperados. Esta conversão é chamada de Serialização. Em nosso dia-à-dia de desenvolvimento pode compreender dois termos:

  • Serialização - converter a instância de uma determinada classe para arquivo;
  • Deserialização - converter (recriar) do arquivo serializado para a instância da classe com os mesmos atributos previamente serializados.

Neste artigo criaremos um projeto com o Windows Forms Application utilizando o Visual C#, onde vamos serializar e deserializar objetos, utilizando diversas técnicas e formatos disponíveis no .NET Framework.  

Desenvolvendo a Aplicação

Crie um novo projeto “Window Forms Application” com a IDE Microsoft Visual C#, define o nome do projeto, ex: AppSerialization e clique no botão salvar.

Para desenvolvimento de nosso projeto, vamos desenvolver 3 classes (Empresa, Funcionario e Departamento), onde empresa possui funcionários e um funcionário é de um departamento, conforme codificação exibida nas listagens 1, 2 e 3. Para a parte visual vamos desenvolver um formulário para acionarmos nossos métodos de serialização e deserialização conforme figura 2 e listagens 4, 5, 6, 7, 8, 9 e 10. Observem nas listagens 1, 2 e 3 a declaração “[Serializable]” antes da classe, esta informação é necessária para todas as classes que serão serializadas. Para um melhor entendimento, documentei todo o código desenvolvido nas listagens.   

   Solution Explorer do nosso projeto

Figura 1: Solution Explorer do nosso projeto

Listagem 1: Classe Departamento

namespace AppSerialization
{
   /// 
    /// Classe Departamento
    /// 
    [Serializable] //indicação para a classe poder ser serializada
    public class Departamento
    {
        private int codigo;
        private string nome;        
        private string sigla;

        /// 
        /// Construtor default
        /// 
        public Departamento()
        {
        }
        
        /// 
        /// Construtor
        /// 
        ///Código do Departamento
        /// Nome do Departamento
        /// Sigla do Departamento
        public Departamento(int codigo, string nome, string sigla)
        {
            this.codigo = codigo;
            this.nome = nome;
            this.sigla = sigla;               
        }

        /// 
        /// Propriedade Código do Departamento
        /// 
        public int Codigo
        {
            get { return codigo; }
            set { codigo = value; }
        }

        /// 
        /// Propriedade Nome do Departamento
        /// 
        public string Nome
        {
            get { return nome; }
            set { nome = value; }
        }

        /// 
        /// Propriedade Sigla do Departamento
        /// 
        public string Sigla
        {
            get { return sigla; }
            set { sigla = value; }
        }
    }
}

Listagem 2: Classe Funcionario

namespace AppSerialization
{
    /// 
    /// Classe Funcionário
    /// 
    [Serializable] //indicação para a classe poder ser serializada
    public class Funcionario
    {
        private int codigo;
        private string nome;
        private string cargo;
        private Departamento depart = new Departamento();

        /// 
        /// Construtor default
        /// 
        public Funcionario()
        {         
        }

        /// 
        /// Construtor
        /// 
        /// Código do Funcionário
        /// Nome do Funcionário
        /// Cargo do Funcionário
        /// Departamento do Funcionário
        public Funcionario(int codigo, string nome, string cargo, Departamento depart)
        {
            this.codigo = codigo;
            this.nome = nome;
            this.cargo = cargo;
            this.depart = depart;
        }

        /// 
        /// Propriedade Código do Funcionário
        /// 
        public int Codigo
        {
            get { return codigo; }
            set { codigo = value; }
        }

        /// 
        /// Propriedade Nome do Funcionário
        /// 
        public string Nome
        {
            get { return nome; }
            set { nome = value; }
        }

        /// 
        /// Propriedade Cargo do Funcionário
        /// 
        public string Cargo
        {
            get { return cargo; }
            set { cargo = value; }
        }

        /// 
        /// Propriedade Departamento do Funcionário
        /// 
        public Departamento Depart
        {
            get { return depart; }
            set { depart = value; }
        }
    }
}

Listagem 3: Classe Empresa

namespace AppSerialization
{
    /// 
    /// Classe Empresa
    /// 
    [Serializable] //indicação para a classe poder ser serializada
    public class Empresa
    {
        private int codigo;
        private string nome;
        private List funcionarios = new List();        

        /// 
        /// Construtor default
        /// 
        public Empresa()
        {
        }

        /// 
        /// Construtor
        /// 
        /// Código da Empresa
        /// Nome da Empresa
        public Empresa(int codigo, string nome)
        {
            this.codigo = codigo;
            this.nome = nome;
        }
                
        /// 
        /// Propriedade Codigo da Empresa
        /// 
        public int Codigo
        {
            get { return codigo; }
            set { codigo = value; }
        }

        /// 
        /// Propriedade Nome da Empresa
        /// 
        public string Nome
        {
            get { return nome; }
            set { nome = value; }
        }

        /// 
        /// Propriedade Funcionários da Empresa
        /// 
        public List Funcionarios
        {
            get { return funcionarios; }
            set { funcionarios = value; }       
        }
    }
}

Abaixo segue design do formulário, onde contém 6 botões para serializar e deserializar, organizados por grupos onde desenvolveremos técnicas de serialização em diversos formatos, como serializar objetos em arquivos binários e XML, e serializar strings em arquivos binários.

  Windows Forms – frMain.cs [Design]

Figura 2: Windows Forms – frMain.cs [Design]

Codificando os métodos do formulário

Após criação da parte visual adicionaremos código ao formulário. Na listagem 4 segue código do construtor, onde crio os objetos, e nas listagens 5 a 10 segue código dos eventos onClick de cada botão, onde faço as serializações e deserializações. 

Listagem 4: Código do Construtor do frMain.cs

public frMain()
{
InitializeComponent();
depar = new Departamento(1, "Desenvolvimento de Sistemas de Informação", "DSI");
funci = new Funcionario(1, "Alessandro Frizzera", "Analista de Sistemas", depar);
empresa = new Empresa(1, "Frizzera Solution S/A");
empresa.Funcionarios.Add(funci);
empresa.Funcionarios.Add(new Funcionario(2, "Shalanna Milfont", "Coordenadora", depar));
empresa.Funcionarios.Add(new Funcionario(2, "Alysson Frizzera", "Programador", depar));
}

Listagem 5: Evento onClick do botão serializar do grupo "Objetos em arquivos binários"

/// 
/// Serializar objeto em formato binário
///         
private void btSerObjBin_Click(object sender, EventArgs e)
{          
    //Criação do arquivo 
    FileStream fs = new FileStream(@"C:\Funcionario.bin", FileMode.Create);

    //Criação de objeto BinaryFormatter para efetuar serialização no formato binário
    BinaryFormatter bf = new BinaryFormatter();

    //Uso do objeto BinaryFormatter para serializar os dados da instância "funci" no arquivo
    bf.Serialize(fs, funci);

    //Fecha arquivo
    fs.Close();
}

Listagem 6: Evento onClick do botão deserializar do grupo "Objetos em arquivos binários"

/// 
/// Deserializar arquivo binário para objeto
/// 
private void btDeserObjBin_Click(object sender, EventArgs e)
{
    FileInfo fi = new FileInfo(@"C:\Funcionario.bin");
    if (fi.Exists)
    {
    //Abertura do arquivo binário para leitura
    FileStream fs = new FileStream(@"C:\Funcionario.bin", FileMode.Open);

    //Criação de objeto BinaryFormatter para efetuar deserialização de formato binário
    BinaryFormatter bf = new BinaryFormatter();

    //Uso do objeto BinaryFormatter para deserializar os dados do arquivo
    Funcionario funcionario = (Funcionario)bf.Deserialize(fs);

    //Fecha arquivo
    fs.Close();

    //Mostrar o resultado da deserialização
    txtResult.Text = funcionario.Nome + " - " + funcionario.Cargo + " - " +             funcionario.Depart.Sigla;
    }
    else txtResult.Text = "Arquivo inexistente.";
}

Listagem 7: Evento onClick do botão Serializar do grupo "Objetos em arquivos XML"

/// 
/// Serializar objeto em formato XML
/// 
private void btSerObjXML_Click(object sender, EventArgs e)
{
    //Criação do arquivo
    FileStream fs = new FileStream(@"C:\Empresa.xml", FileMode.Create);

    //Criação de objeto XmlSerializer para efetuar a serialização em formato XML
    XmlSerializer xs = new XmlSerializer(typeof(Empresa));

    //Uso do objeto XmlSerializer para serializar os dados no arquivo
    xs.Serialize(fs, empresa);

    //Fecha o arquivo
    fs.Close();
}

Listagem 8: Evento onClick do botão Deserializar do grupo "Objetos em arquivos XML"

/// 
/// Deserializar arquivo XML para objeto
/// 
private void btDeserObjXML_Click(object sender, EventArgs e)
{
    FileInfo fi = new FileInfo(@"C:\Empresa.xml");
    if (fi.Exists)
    {
    //Abertura do arquivo xml para leitura
    FileStream fs = new FileStream(@"C:\Empresa.xml", FileMode.Open);

    //Criação do objeto XmlSerializer para efetuar deserialização de formato XML
    XmlSerializer xs = new XmlSerializer(typeof(Empresa));

    //Uso do objeto XmlSerializer para deserializar os dados do arquivo
    Empresa emp = (Empresa)xs.Deserialize(fs);

    //fecha o arquivo
    fs.Close();

    //Mostrar o resultado da deserialização
    txtResult.Text = emp.Nome;
    }
    else txtResult.Text = "Arquivo inexistente.";
}

Listagem 9: Evento onClick do botão Serializar do grupo "Textos em arquivo binários"

/// 
/// Serializar string em formato binário
/// 
private void btSerTextoBin_Click(object sender, EventArgs e)
{
    //serializar string
    string data = "Este texto será gravado no arquivo via serialização.";

    //Criação do arquivo para salvar o dado
    FileStream fs = new FileStream(@"C:\SerializedString.data", FileMode.Create);

    //Criação do objeto BinaryFormatter para efetuar serialização no formato binário
    BinaryFormatter bf = new BinaryFormatter();

    //Uso do objeto BinaryFormatter para serializar os dados no arquivo
    bf.Serialize(fs, data);

    //fecha o arquivo
    fs.Close();
}

Listagem 10: Evento onClick do botão Deserializar do grupo "Textos em arquivo binários"

/// 
/// Deserializar arquivo binário para string
/// 
private void btDeserTextoBin_Click(object sender, EventArgs e)
{
    FileInfo fi = new FileInfo(@"C:\SerializedString.data");
    if (fi.Exists)
    {
    //Abertura do arquivo binário para leitura
    FileStream fs = new FileStream(@"C:\SerializedString.data", FileMode.Open);

    //Criação de objeto BinaryFormatter para efetuar deserialização de formato binário
    BinaryFormatter bf = new BinaryFormatter();

    //Uso do objeto BinaryFormatter para deserializar os dados do arquivo
    string data = (string)bf.Deserialize(fs);

    //Fecha arquivo
    fs.Close();

    //Mostrar o resultado da deserialização
    txtResult.Text = data;
    }
    else txtResult.Text = "Arquivo inexistente.";
}