Tipos de valor armazenam diretamente seus valores, enquanto tipos de referência armazenam endereços de memória. Essa distinção impacta significtaivamente como os dados são gerenciados na memória.
Tipos de valor são armazenados na pilha, enquanto tipos de referência possuem seu conteúdo na heap. A diferença principle está no local de alocação e no comportamento durante operações de cópia.
A memória é dividida em quatro áreas principais:
- Área de dados globais: variáveis globais, dados estáticos e constantes
- Área de código: instruções do programa
- Área da pilha: variáveis locais, parâmetros e retornos
- Área da heap: memória gerenciada pelo CLR
Exemplo prático com tipos de valor:
int num1 = 5;
int num2 = num1; // Cópia direta do valor
num1 = 10; // Não afeta num2
Exemplo com tipos de referência:
class TesteReferencia {
public int Valor { get; set; }
}
public static void Main() {
TesteReferencia objA = new TesteReferencia { Valor = 20 };
TesteReferencia objB = objA;
Console.WriteLine("Antes: Valor de objA = {0}", objA.Valor);
Console.WriteLine("Antes: Valor de objB = {0}", objB.Valor);
objB.Valor = 15; // Altera ambos os objetos
Console.WriteLine("Depois: Valor de objA = {0}", objA.Valor);
Console.WriteLine("Depois: Valor de objB = {0}", objB.Valor);
}
Comportamento de parâmetros:
class TesteParametros {
public int Valor { get; set; }
}
public static void Main() {
TesteParametros obj = new TesteParametros { Valor = 10 };
AlterarObjeto(obj); // Altera apenas o valor
AlterarReferencia(ref obj); // Substitui a referência
Console.WriteLine("Valor final: {0}", obj.Valor);
}
public static void AlterarObjeto(TesteParametros obj) {
obj.Valor = 20;
obj = null; // Não afeta a referência externa
}
public static void AlterarReferencia(ref TesteParametros obj) {
obj.Valor = 30;
obj = new TesteParametros { Valor = 100 }; // Substitui a referência
}
Cópia Profunda e Cópia Superficial
Cópia superficial cria uma nova referência para o mesmo objeto, mantendo a ligação entre os objetos. Cópia profunda cria uma cópia completa dos dados.
Exemplo de cópia superfiical:
List<string> listaOriginal = new List<string> { "A", "B", "C" };
List<string> listaSuperficial = listaOriginal;
listaSuperficial.Add("D"); // Altera ambas as listas
</string></string></string>
Exemplo de cópia profunda:
List<string> listaOriginal = new List<string> { "A", "B", "C" };
List<string> listaProfunda = new List<string>(listaOriginal);
listaProfunda.Add("D"); // Não afeta a lista original
</string></string></string></string>
Strings e arrays:
- Strings são objetos de referência, mas se comportam como valores devido à implementação interna
- Arrays sempre são cópias superficiais, exigindo alocação explícita para cópia profunda