Olá Pessoal, Vou fazer uma série sobre (C Sharp) C# para iniciantes.

Atendendo à diversos pedidos vou procurar abordar de uma forma diferente a transferência de conhecimentos nessa linguagem, apostila e tutorial tem de monte na internet, a intenção não é essa, vamos abordar necessidades reais de quem quer dar os primeiros passos em C# e agora quer aprender mais.

Só para começar, um pouquinho de história:
O C# é uma linguagem derivada do C++, mas também tem base em Java e Object Pascal.
Criada em meados de 1999 por Anders Hejlsberg (pai do Turbo Pascal e Delphi) vem desde 2001 ganhando espaço e se tornou uma das linguagens mais populares da atualidade.

Vamos dar o primeiro passo:

Variáveis

Toda variável é uma alocação de uma quantidade de memória, é nesse espaço de memória que está armazenado o conteúdo da variável, internamente uma variável possui um ponteiro, o ponteiro para o sistema operacional é um endereçamento físico de memória, serve para localizar onde está armazenado tal dado.

A declaração de variável em C#:

int MeuInteiro;

Deve-se sempre inicializar uma variável:

int MeuInteiro = 0;

Stack e Heap

O gerenciamento da memória no C# é feito em duas áreas de memória, o Stack e o Heap.

O Stack é uma área bem pequena de memória (alguns KB) e funciona no formato de pilha.

Pilha é uma estrutura de dados em que a inserção e a remoção de elementos de uma sequência se faz pela mesma extremidade, geralmente designada por topo da pilha”

Ou seja, o último que entra na pilha é o primeiro que sai (LIFO – Last-In-First-Out)
Qualquer dado inserido na Stack é automaticamente retirado automaticamente após a conclusão do processo que a alocou, isso livra o programador de se preocupar com isso.
Quando a Stack atinge seu tamanho máximo temos um problema muito conhecido como “stack overflow”. Os dados armazenados na Stack são chamados de “Value Types”.

A Heap é uma área de memória bem grande, diferente da Stack que é pequena, seu tamanho muda dinamicamente conforme o uso, a Heap é acessada indiretamente, por meio de referência, por isso chamamos os dados da Heap de “Reference Type”.
Existe um processo chamado Garbage Collector (GC) que é responsável pela limpeza desta área de memória.

O custo de se criar um objeto na Heap é muito maior do que na Stack, sendo assim na área de memória Stack nós temos os Value Types a seguir:
Tipos numéricos (int, long, short etc), ponto flutuante (float, double), decimal, booleanos (true e false) e estruturas definidas pelo usuário (struct).

Na Heap nós temos os Reference Types do tipo: Classes, Interfaces e Delegates.

As características dos tipos alocados em cada uma dessas áreas são as seguintes:

Value Types:

Reference Types:

Boxing e Unboxing

Boxing é o processo de converter um “Value Type” para o tipo de object ou a qualquer tipo de interface implementada por este tipo de valor “Reference Type”.

Unboxing extrai o “Value Type” do objeto. Transforma um objeto em um tipo simples.

// Vamos fazer um Boxing
int i = 123;
object obj = i;

// Agora vamos fazer Unboxing
obj = 123;
i = (int)obj;

Simples né?

O Garbage Collector (GC)

Como na Heap todos objetos são referenciados, o GC verifica se existe alguma variável fazendo referência a determinado objeto, caso não encontre ele desaloca “Coleta” aquela área de memória.

Um fato interessante, por mais que se chame o Garbage Collector a sensação que temos é de que ele irá entrar em ação no mesmo instante, mas não, estamos apenas sinalizando a ele. “Passe por aqui GC”.

Não é recomendado chamar manualmente o GC, deixe com que ele trabalhe de sua forma.
Abaixo estamos chamando o GC, porém sinalizando para que ele aguarde o trabalho em memória terminar:

GC.Collect();
GC.WaitForPendingFinalizers();

Passagem de Valor ou por Referência

Dada as funções:

public void FuncaoPorValor(int numero)
{
    numero = 10;
}

public void FuncaoPorReferencia(ref int numero)
{
    numero = 10;
}

A única diferença entre as duas é que uma trata a variável “numero” passada por valor e a outra trata a variável “numero” por referência.

Observemos os resultados:

int variavel = 0;
FuncaoPorValor(variavel);

MessageBox.Show("Resultado = " + variavel.ToString());
// Resultado = 0 Foi passada uma cópia da variável pro método.

int variavel2 = 0;
FuncaoPorReferencia(variavel2);

MessageBox.Show("Resultado = " + variavel2.ToString());
// Resultado = 10 Foi passada a referência da variável pro método.

Normalmente quando passamos uma variável para uma função, estamos passando uma cópia dela para a função trabalhar.
Caso essa cópia seja modificada a original permanece igual.

Quando passamos a variável por referência, um ponteiro de memória está sendo passado, ou seja, caso seja modificada a própria variável está sendo alterada, pois o ponteiro de memória aponta para a alocação original.

E por hoje ficamos por aqui.
Espero que aproveitem e em caso de dúvidas podem postá-las nos comentários.

Referências:

Tchau e Obrigado!