Introdução ao .Net Framework – Parte 6 – Boxing e Unboxing

Fala galera, blz?

Sexta publicação da série introdução ao .Net Framework. Nesse post falarei sobre boxing e unboxing de tipos. Você sabia que pode estar realizando operações que podem estar diminuindo a performance do seu código?

Para quem não leu os post anteriores, recomendo que leiam, segue os link’s.

1 – Introdução ao .Net Framework – Parte 1 – Do que é composto, compialçao.

2 – Introdução ao .Net Framework – Parte 2 – CLR, CTS, FCL, CLS.

3 – Introdução ao .Net Framework – Parte 3 – Tipos.

4 – Introdução ao .Net Framework – Parte 4 – Conversão/Casting de tipos.

5 – Introdução ao .Net Framework – Parte 5 – Namespace e Assemblies.

INTRODUÇÃO 

Diferente dos tipos de referência os tipos de valor não são alocados na memória heap, não são referenciados e não sofrem coleta de lixo. Até aqui está claro que um tipo valor, quando falamos em desempenho, é melhor que um tipo-referência. Então porque não utilizamos mais tipos de valor? Existem várias respostas para essa pergunta, mas, em minha opinião, o principal fator é a facilidade de se trabalhar com classes.

Já sabemos como funciona a conversão entre um tipo de referência para outro tipo referência e de um tipo-valor para outro tipo-valor. Agora vamos entender como o framework se comporta na conversão de um tipo valor para um tipo-referência. Esse tipo de conversão é chamado de Boxing.

BOXING DE TIPOS-VALOR

É comum declararmos uma variável de tipo valor e em algum momento precisar obter uma referência da instancia criada desse tipo. Irei mostrar um exemplo passo a passo para ficar fácil o entendimento. Veja o código abaixo:

C#


public class MinhaClasse
{
 //declarando uma struct
 //struct é um tipo valor
 struct ExemploStruct
 {
 public int a, b;
 }

 void Main()
 {
 //declarando um objeto ArrayList
 //esse objeto se encontra no namespace System.Collections
 ArrayList Aux = new ArrayList();

 //declarando uma variavel do tipo ExemploStruct
 //Como esse tipo é uma struct
 //seu valor será guardado na memória stack
 ExemploStruct Ex;

 }

}

No código acima foi criada a classe MinhaClasse e dentro da classe foi criado um tipo struct chamado ExemploStruct e um método void, por enquanto você só precisa saber que void é um tipo de método que não tem retorno, chamando Main. O tipo struct é um tipo valor que é tipicamente usado para encapsular pequenos grupos de variáveis, como por exemplo, coordenadas ou características de um retângulo.  Dentro de ExemploStruct foram criadas duas variáveis do tipo System.Int32, “a” e “b”. No método Main() foi criado um objeto do tipo ArrayList e logo abaixo declarado uma variável do tipo ExemploStruct. O tipo ArrayList está presente dentro do namespace System.Collections. Com esse tipo é possível se trabalhar com lista, sendo que, seu tamanho pode ser aumentando de acordo com a necessidade. O ArrayList possui alguns métodos e um deles é muito usado, o Add. O método Add adiciona um objeto no final do ArrayList. Veja agora o mesmo código com mais um trecho implementado, usando o método Add:

C#


public class MinhaClasse
{
 //declarando uma struct
 //struct é um tipo valor
 struct ExemploStruct
 {
 public int a, b;
 }

void Main()
 {
 //declarando um objeto ArrayList
 //esse objeto se encontra no namespace System.Collections
 ArrayList Aux = new ArrayList();

//declarando uma variavel do tipo ExemploStruct
 //Como esse tipo é uma struct
 //seu valor será guardado na memória stack
 ExemploStruct Ex;

for (int i = 0; i < 5; i++)
 {
 Ex.a = 1; //Atribuindo valor a variavel a do tipo ExemploStruct
 Ex.b = 2; //Atribuindo valor b variavel a do tipo ExemploStruct
 Aux.Add(Ex);
 }

 }

Veja que foi criado um laço de repetição usando um for. Nesse laço eu inicializado as variáveis do tipo ExemploStruct e uso o método Add do meu objeto ArrayList para adicionar a instancia de ExemploStruct dentro de sua lista. Todo loop que ocorrer dentro desse for uma nova instancia de ExemploStruct será criada e adicionada dentro do ArrayList. Lembra quando eu disse quando que o método Add do tipo ArrayList adiciona um objeto no final da lista? Lembram também que um objeto é uma referência (ponteiro) que aponta para o local onde está armazenado seus valores na memória heap? Ou seja, para que o método Add funcione vamos ter que converter o tipo ExemploStruct em um objeto, essa conversão é chamada de boxing. Mas, só precisamos fazer essa conversão explicitamente em algumas linguagens, como o C++. O compilador do C# faz isso automaticamente!

Lembrando que, para se trabalhar com objetos, mais recursos de processamento são usados como foi explicado no início desse post.  Tranquilo o boxing  né? Vejamos agora o Unboxing.

UNBOXING DE TIPOS VALOR

Ainda analisando o código usado como exemplo para entendermos o boxing, imagine que em um momento da aplicação seja necessário obter um determinado valor do ArrayList, como isso seria feito? Veja o exemplo abaixo:

C#

 

//Declarando um tipo valor ExemploStruct
 ExemploStruct ExUnboxing;

/*Atribuindo o primeiro valor do ArrayList para a variavel ExUnboxing
 usando casting*/
 ExUnboxing = (ExemploStruct) Aux[0];

Neste exemplo estou pegando o ponteiro contido no objeto do primeiro elemento do ArrayList e tentando coloca-lo na variável de tipo valor ExUnboxing. Para isso funcionar o CLR realizará dois passo.

1. Obter o endereço do objeto (boxed) na memória heap, esse primeiro passo é chamado do unboxing.

2. Os valores armazenados na memória heap são copiados para a instancia criada de tipo valor armazenada na memória stack.

Se juntarmos esses dois passos realizados a operação de unboxing se torna exatamente o oposto de boxing, entretanto, não se confunda, pois, o processo denominado unboxing é somente o primeiro.

Reforçando o que eu já disse, as operações realizadas no boxing e unboxing podem causar uma queda de desempenho na aplicação. Deve-se tomar cuidado com o casting realizado no unboxing para que exceções não sejam disparadas caso o objeto contido no elemento do ArrayList seja nulo ou de um tipo diferente do tipo que o receberá.

CONCLUSÃO

Em alguns momentos pode ser necessário realizar o boxing de um tipo valor para poder utilizar um método que requer um tipo referência. Eu mostrei um exemplo com essa publicação, mas, não quer dizer que seja o único.

Espero que esse conteúdo seja útil para alguém.

Até o próximo post!

REFERÊNCIAS

               struct (C# Reference)http://msdn.microsoft.com/en-us/library/ah19swz4.aspx

               Classe ArrayListhttp://msdn.microsoft.com/pt-br/library/system.collections.arraylist(v=vs.110).aspx

              Programação aplicada com Microsoft .Net Framework – Jeffrey Richter

 

 

Anúncios

2 comentários sobre “Introdução ao .Net Framework – Parte 6 – Boxing e Unboxing

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s