Generics
Aprenda em detalhes um dos recursos mais poderosos do C#
Quando utilizamos coleções em qualquer plataforma estamos considerando algoritmos que possam ser aplicados com vários tipos, como string, número e tipos customizados. Por exemplo, quando consideramos o conceito de fila, procuramos alguma coleção que possa oferecer este tipo de algoritmo. Qualquer biblioteca/plataforma de uso profissional tem suporte para coleções. A plataforma .NET tem um grande conjunto destas coleções. Na versão 1.x algumas se tornaram populares como ArrayList, Hashtable e assim por diante. Mas existe um tipo que é o mais popular de todos: Array.
Lendo a documentação das classes ArrayList ou Hashtable, vamos perceber que os métodos para manipular a coleção recebem ou retornam itens do tipo Object, por exemplo, o método ArrayList.Add:
public virtual int Add(
Object value
)
Quando atribuímos uma referência, por exemplo, System.String a um ponteiro que tem como tipo base um Object, como o parâmetro value do método Add acima, estamos fazendo com que mecanismo de execução do CLR percorra estruturas internas e aplique certas regras para garantir que tal atribuição seja válida. E neste caso a atribuição só funciona pois todos os objetos são derivados, direta ou indiretamente da classe Object.
A plataforma .NET tem dois tipos fundamentais: Reference type e Value type. Um Reference type é, em uma comparação simples, similar ao conceito de ponteiro em linguagens de programação não gerenciadas, como C, C++, Object Pascal e assim por diante. Ou seja, uma variável A do tipo Object tem o endereço de memória onde o objeto real está armazenado. Portanto, o valor de A é o endereço do objeto, ou seja, uma referência para ele. Um Value type, como um Int32, contém o objeto. Ou seja, uma variável A do tipo Int32 é o objeto e não uma referência para um endereço.
É claro que em ambientes gerenciados como a plataforma .NET, existem outras estruturas de controles além de um endereço de memória apenas. Por isto mesmo, o ambiente tem conceitos como Managed Environment e Managed Execution, ou seja, boa parte do que se faz está sob a supervisão constante do ambiente que o executa. Eu digo boa parte, pois é possível integrar código não gerenciado em código gerenciado e este código não gerenciado NÃO está sob a supervisão do ambiente gerenciado.
Voltando aos conceitos de Reference type e Value type. Um Value type representa o valor em si e, portanto, da perspectiva do CLR você não pode simplesmente atribuir um número para um Object, pois são conceitos completamente distintos. Outros ambientes utilizam conceitos de Object de maneira ortogonal, ou seja, tudo é um objeto e você pode atribuir livremente um objeto para outro, pois todos pertencem ao mesmo conceito base.
Na plataforma .NET não é assim. Mas existem meios, utilizando recursos seguros das linguagens de programação, de atribuir um Value type para uma Reference type. Um destes meios é a sobrecarga de operadores, onde você pode fazer com que um tipo Produto seja somado como um tipo Int32 e tenha como resultado um reajuste.
Também existe uma possibilidade comum que a própria plataforma .NET realiza sem intervenção do programador: O BOX e UNBOX.
Conceituando Box e Unbox
Quando você, na sua casa, quer guardar algo, logo procura uma caixa. Uma caixa aceita praticamente qualquer coisa. Bom, uma variável do tipo Object também. Se você coloca algo em uma caixa e fecha, e depois entrega para alguém, a primeira pergunta da inocente vítima é:
“- O que tem aí?”
Bem, é exatamente isto que acontece quando você atribui algo para uma variável do tipo Object. Somente quem guardou "aquilo" na caixa sabe o que é. Veja um exemplo:
Box(Colocar na caixa):
Int32 value = 10;
Object caixa = value;
Unbox(Abrir e caixa e torcer):
String vitima = (String)caixa;
Pelo exemplo acima você já imagina que a surpresa é desagradável. Se tentar compilar este código, ele não vai apresentar erros na compilação. O compilador, sem opção, acredita que o escritor do código saiba o que está fazendo. Quando ele tenta remover da caixa, acredita que existe uma string e quando percebe que não é o que o código diz, só resta lançar uma InvalidCastException. É o equivalente àquele sorriso amarelo quando ganha um presente sem o menor sentido.
Coleções
Voltando às coleções ArrayList e Hashtable, elas podem conter objetos de vários tipos ao mesmo tempo, o que é muito "
ATENÇÃO! A exibição deste artigo foi interrompida.
Este é um post disponível para assinantes MVPSaiba como acessar este post através de Créditos DevMedia:
Assinatura de Créditos – Aqui este post custa
R$ 1,47Com esse plano você compra R$ 180,00 em créditos e ganha, em média, 80% de desconto no preço do post.
Assine agora Plano ocasional - Aqui este post custa:
R$ 1,96 (assinante) ou
R$ 2,45 (não-assinante)
Você compra um mínimo de R$ 60,00 em créditos e ganha, em média, 50% de desconto no preço do post.
Compre agora Plano conveniência – Neste plano este post custa
R$ 4,90
Neste plano você compra somente um post, pagando seu preço sem desconto.
Compre agora