Exercício - Descubra os tipos de referência
- 8 minutos
Os tipos de referência incluem matrizes, classes e cadeias de carateres. Os tipos de referência são tratados de forma diferente dos tipos de valor em relação à maneira como os valores são armazenados quando o aplicativo está sendo executado.
Neste exercício, você aprenderá como os tipos de referência são diferentes dos tipos de valor e como usar o new operador para associar uma variável a um valor na memória do computador.
De que forma os tipos de referência são diferentes dos tipos de valor
Uma variável de tipo de valor armazena seus valores diretamente em uma área de armazenamento chamada pilha. A pilha é memória alocada para o código que está atualmente em execução na CPU (também conhecida como frame de pilha ou frame de ativação). Quando a frame de pilha termina a execução, os valores na pilha são removidos.
Uma variável de tipo de referência armazena seus valores em uma região de memória separada chamada heap. A área dinâmica para dados é uma área de memória que é partilhada entre várias aplicações em execução no sistema operativo em simultâneo. O .NET Runtime comunica com o sistema operativo para determinar que endereços de memória estão disponíveis e pede um endereço no qual possa armazenar o valor. O .NET Runtime armazena o valor e, em seguida, devolve o endereço de memória à variável. Quando o seu código utiliza a variável, o .NET Runtime procura automaticamente o endereço armazenado na variável e obtém o valor aí armazenado.
Em seguida, você escreverá algum código que ilustre essas ideias com mais clareza.
Definir uma variável de tipo de referência
Exclua ou use o operador
//de comentário de linha para comentar todo o código dos exercícios anteriores.Atualize seu código no Editor de Códigos do Visual Studio da seguinte maneira:
int[] data;O código anterior define uma variável que pode conter um valor de matriz de tipo
int.Nesta fase,
dataé meramente uma variável que pode conter uma referência, ou seja, um endereço de memória de um valor na área dinâmica para dados. Como não está a apontar para um endereço de memória, é chamada de referência nula.Criar uma instância de
intmatriz usando anewpalavra-chaveAtualize seu código no Editor de Códigos do Visual Studio para criar e atribuir uma nova instância de
intmatriz, usando o seguinte código:int[] data; data = new int[3];A
newpalavra-chave informa o .NET Runtime para criar uma instância de matriz e, em seguida, coordene-se com o sistema operacional para armazenar a matriz dimensionadaintpara três valores int na memória. O .NET Runtime concorda e devolve um endereço de memória da nova matrizint. Por fim, o endereço de memória é armazenado nos dados da variável. Os elementos da matrizintsão predefinidos para o valor0, uma vez que esse é o valor predefinido deint.Modifique o exemplo de código para executar ambas as operações em uma única linha de código
As duas linhas de código na etapa anterior são normalmente encurtadas para uma única linha de código para declarar a variável e criar uma nova instância da
intmatriz. Modifique o código do passo 3 para o seguinte.int[] data = new int[3];Embora não haja nenhuma saída a ser observada, esperamos que este exercício tenha adicionado clareza à forma como a sintaxe C# se relaciona com as etapas do processo para trabalhar com tipos de referência.
O que há de diferente no tipo de dados de cadeia de caracteres C#?
O tipo de dados string também é um tipo de referência. Você pode estar se perguntando por que um new operador não foi usado ao declarar uma cadeia de caracteres. Esta é apenas uma conveniência destinada aos designers do C#. Como o tipo de string dados é usado com tanta frequência, você pode usar este formato:
string shortenedString = "Hello World!";
Console.WriteLine(shortenedString);
Nos bastidores, no entanto, uma nova instância de System.String é criada e inicializada para "Hello World!".
Preocupações práticas com a utilização de valores e tipos de referência
-
Tipo de valor (int): Neste exemplo,
val_Aeval_Bsão tipos de valor inteiro.
int val_A = 2;
int val_B = val_A;
val_B = 5;
Console.WriteLine("--Value Types--");
Console.WriteLine($"val_A: {val_A}");
Console.WriteLine($"val_B: {val_B}");
Deverá ver o seguinte resultado:
--Value Types--
val_A: 2
val_B: 5
Quando val_B = val_A é executado, o valor de val_A é copiado e armazenado em val_B. Assim, quando val_B é alterado, val_A permanece inalterado.
-
Tipo de referência (matriz): Neste exemplo,
ref_Aeref_Bsão tipos de referência de matriz.
int[] ref_A= new int[1];
ref_A[0] = 2;
int[] ref_B = ref_A;
ref_B[0] = 5;
Console.WriteLine("--Reference Types--");
Console.WriteLine($"ref_A[0]: {ref_A[0]}");
Console.WriteLine($"ref_B[0]: {ref_B[0]}");
Deverá ver o seguinte resultado:
--Reference Types--
ref_A[0]: 5
ref_B[0]: 5
Quando ref_B = ref_A é executado, ref_B aponta para o mesmo local de memória que ref_A. Assim, quando ref_B[0] é alterado, ref_A[0] também muda porque ambos apontam para o mesmo local de memória. Esta é uma diferença fundamental entre tipos de valor e tipos de referência.
Recapitulação
- Os tipos de valor podem conter valores mais pequenos e são armazenados na pilha. Os tipos de referência podem conter valores grandes e é criada uma nova instância de um tipo de referência com o operador
new. As variáveis de tipo de referência contêm uma referência (o endereço de memória) para o valor real armazenado na área dinâmica para dados. - Os tipos de referência incluem matrizes, cadeias de carateres e classes.