Tipos de Valor e Tipos de Referência em C#: Cópia Profunda e Cópia Superficial

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

Tags: tipos-de-valor tipos-de-referência cópia-profunda cópia-superficial CSharp

Publicado em 10-8 09:34