Tipos de dados em C#

Jones Roberto Nuzzi
5 min readOct 24, 2019

--

Eu sei pessoal, isso é básico. Mas ultimamente tenho passado conhecimento para jovens aprendizes, e tenho notado uma certa dificuldade em entender sobre o assunto, por isso vou tentar exemplificar de uma forma simples e concisa como funcionam os tipos de dados em C#.

Sobre o C#

C# é uma linguagem fortemente tipada. Isso significa que devemos declarar o tipo de uma variável que indica o valor que ela armazenará, como um número int, um float ou decimal, string etc.

O exemplo de código a seguir declara e inicializa variáveis ​​de diferentes tipos de dados.

O C# separou os tipos de dados em dois: tipos valor (value types) e tipos referência (reference types). Os tipos de valor incluem tipos simples (por exemplo, int, float, bool e char), enum, struct e Nullable. Os tipos de referência incluem class, interface, delegates e arrays.

divisão de tipos de dados em C#

Diferença entre um tipo de valor e um tipo de referência

Um tipo de valor mantém os dados dentro de sua própria alocação de memória e um tipo de referência contém um ponteiro para outro local da memória que mantém os dados reais. As variáveis ​​de tipo de referência são armazenadas na heap, enquanto as variáveis ​​de tipo de valor são armazenadas na stack.

Tipo de valor

Um tipo valor armazena seu conteúdo na memória alocada na stack. Quando você cria um tipo valor, um único espaço na memória é alocado para armazenar o valor e essa variável mantém diretamente um valor. Se você atribui-lo a outra variável, o valor é copiado diretamente e as duas variáveis ​​funcionam independentemente. datatypes, structs e enum também são tipo valor e funcionam da mesma maneira. Tipo valor podem ser criados em tempo de compilação e Armazenados na stack, por isso, o Garbage collector não pode acessar a pilha.

por exemplo:

int x = 5;

Aqui o valor 5 é armazenado em uma área da memória stack.

Tipo de referência

Os tipos referência mantém uma referência (endereço) ao objeto, mas não para o próprio objeto. Como os tipos referência representam o endereço da variável e não os dados em si, a atribuição de uma variável de tipos referência a outra não copia os dados. Em vez disso, cria uma segunda cópia da referência, que se refere ao mesmo local do heap que o valor original. As variáveis ​​do tipos referência são armazenadas em uma área diferente da memória chamada heap. Isso significa que, quando uma variável do tipo de referência não é mais usada, ela pode ser marcada para Garbage collector. Exemplos de tipos de referência são class, object, arrays, interfaces etc.

int[] myArray = new int[10];

No código acima, o espaço necessário para os 10 números inteiros que compõem o array é alocado no heap.

Stack e Heap

A stack é usada para alocação de memória estática e heap para alocação de memória dinâmica, ambas armazenadas na RAM do computador.

As variáveis ​​alocadas na stack são armazenadas diretamente na memória e o acesso a essa memória é muito rápido, e sua alocação é tratada quando o programa é compilado. A stack é sempre reservada em uma ordem LIFO (last-in-first-out), o bloco reservado mais recente é sempre o próximo bloco a ser liberado. Isso torna muito simples acompanhar a stack, liberar um bloco da stack nada mais é do que ajustar um ponteiro.

As variáveis ​​alocadas no heap têm sua memória alocada em tempo de execução e o acesso a essa memória é um pouco mais lento, mas o tamanho do heap é limitado apenas pelo tamanho da memória virtual. O elemento da heap não tem dependências entre si e sempre pode ser acessado aleatoriamente a qualquer momento. Você pode alocar um bloco a qualquer momento e liberá-lo a qualquer momento. Isso torna muito mais complexo acompanhar quais partes do heap estão alocadas ou livres a qualquer momento.

Você pode usar a stack se souber exatamente a quantidade de dados que precisa alocar antes do tempo de compilação e esse espaço não for muito grande. Você pode usar o heap se não souber exatamente quantos dados precisará no tempo de execução ou se precisar alocar muitos dados.

Em uma situação multithread, cada thread terá sua própria stack completamente independente, mas eles compartilharão o heap.

Classe e Estrutura

Tecnicamente falando, struct e class são quase equivalentes.A principal diferença é que uma classe é mais flexível para combinar dados e métodos e fornece a reutilização por herança. O struct normalmente deve ser usado para agrupar dados. A diferença técnica é que a classe é passada por referência e a estrutura é passada por cópia, significa que uma classe é um tipo referência e seu objeto é criado na memória heap e estrutura é um tipo valor e seu objeto é criado na memória da stack.

A classe pode criar uma subclasse que herdará as propriedades e os métodos dos pais, enquanto o struct não suporta a herança.

Uma classe tem todos os membros privados por padrão. Uma estrutura tem todos os membros públicos por padrão.

As classes ficam na heap onde o Garbage collector é ativo e os objetos são geralmente desalocados quando a instância não é mais referenciada por outro código. As estruturas ficam na stack onde o Garbace collector não é ativo , portanto, não há gerenciamento de memória eficiente.

Tamanho da classe vazia é 1 Byte, em que Tamanho da estrutura vazia é 0 Bytes

Vou ficando por aqui pessoal, nos próximos artigos irei começar a falar sobre as novidades no C#, .Net Core e visual studio.

--

--

Jones Roberto Nuzzi

Arquiteto de Sistemas na Riza Asset, Sempre focado em desenvolvimento de sistemas para o mercado financeiro, com mais de 15 anos de experiência!