Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Uma instrução de declaração declara uma nova variável local, constante local ou variável de referência local. Para declarar uma variável local, especifique seu tipo e forneça seu nome. Você pode declarar várias variáveis do mesmo tipo em uma instrução, como mostra o seguinte exemplo:
string greeting;
int a, b, c;
List<double> xs;
Em uma instrução de declaração, você também pode inicializar uma variável com seu valor inicial:
string greeting = "Hello";
int a = 3, b = 2, c = a + b;
List<double> xs = new();
Os exemplos anteriores especificam explicitamente o tipo de uma variável. Você também pode deixar o compilador inferir o tipo de uma variável de sua expressão de inicialização. Para fazer isso, use a palavra-chave var
em vez do nome de um tipo. Para saber mais, confira a seção Variáveis locais de tipo implícito.
Para declarar uma constante local, use a palavra-chave const
, como mostra o seguinte exemplo:
const string Greeting = "Hello";
const double MinLimit = -10.0, MaxLimit = -MinLimit;
Ao declarar uma constante local, você também deve inicializá-la.
Para obter informações sobre variáveis de referência local, confira a seção Variáveis de referência.
Variáveis locais tipadas implicitamente
Ao declarar uma variável local, você pode deixar o compilador inferir o tipo da variável da expressão de inicialização. Para fazer isso, use a palavra-chave var
em vez do nome de um tipo:
var greeting = "Hello";
Console.WriteLine(greeting.GetType()); // output: System.String
var a = 32;
Console.WriteLine(a.GetType()); // output: System.Int32
var xs = new List<double>();
Console.WriteLine(xs.GetType()); // output: System.Collections.Generic.List`1[System.Double]
Como mostra o exemplo anterior, variáveis locais de tipo implícito são fortemente tipadas.
Observação
Quando você usa var
no contexto com reconhecimento anulável habilitado e o tipo de uma expressão de inicialização é um tipo de referência, o compilador sempre infere um tipo de referência anulável mesmo que o tipo de uma expressão de inicialização não seja anulável.
Um uso comum de var
é com uma expressão de invocação de construtor. O uso de var
permite não repetir um nome de tipo em uma declaração de variável e instanciação de objeto, como mostra o exemplo a seguir:
var xs = new List<int>();
Você pode usar uma expressão new
com tipo de destino como alternativa:
List<int> xs = new();
List<int>? ys = new();
Ao trabalhar com tipos anônimos, você deve usar variáveis locais tipadas implicitamente. O exemplo a seguir mostra uma expressão de consulta que usa um tipo anônimo para conter o nome e o número de telefone de um cliente:
var fromPhoenix = from cust in customers
where cust.City == "Phoenix"
select new { cust.Name, cust.Phone };
foreach (var customer in fromPhoenix)
{
Console.WriteLine($"Name={customer.Name}, Phone={customer.Phone}");
}
No exemplo anterior, você não pode especificar explicitamente o tipo da variável fromPhoenix
. O tipo é IEnumerable<T>, mas nesse caso T
é um tipo anônimo e você não pode fornecer seu nome. É por isso que você precisa usar var
. Pelo mesmo motivo, você deve usar var
ao declarar a variável de iteração customer
na instrução foreach
.
Para obter mais informações sobre variáveis locais tipadas implicitamente, confira Variáveis locais tipadas implicitamente.
Na correspondência de padrões, a palavra-chave var
é usada em um var
padrão.
Variáveis de referência
Ao declarar uma variável local e adicionar a palavra-chave ref
antes do tipo da variável, você declara uma variável de referência ou um local ref
:
ref int aliasOfvariable = ref variable;
Uma variável de referência é uma variável que se refere a outra variável, que é chamada de referenciante. Ou seja, uma variável de referência é um alias para seu referenciante. Quando você atribui um valor a uma variável de referência, esse valor é atribuído ao referenciador. Quando você lê o valor de uma variável de referência, o valor do referenciante é retornado. O exemplo a seguir demonstra esse comportamento:
int a = 1;
ref int aliasOfa = ref a;
Console.WriteLine($"(a, aliasOfa) is ({a}, {aliasOfa})"); // output: (a, aliasOfa) is (1, 1)
a = 2;
Console.WriteLine($"(a, aliasOfa) is ({a}, {aliasOfa})"); // output: (a, aliasOfa) is (2, 2)
aliasOfa = 3;
Console.WriteLine($"(a, aliasOfa) is ({a}, {aliasOfa})"); // output: (a, aliasOfa) is (3, 3)
Use o ref
operador de atribuição = ref
para alterar o referente de uma variável de referência, como mostra o exemplo a seguir:
void Display(int[] s) => Console.WriteLine(string.Join(" ", s));
int[] xs = [0, 0, 0];
Display(xs);
ref int element = ref xs[0];
element = 1;
Display(xs);
element = ref xs[^1];
element = 3;
Display(xs);
// Output:
// 0 0 0
// 1 0 0
// 1 0 3
No exemplo anterior, a variável de referência element
é inicializada como um alias para o primeiro elemento de matriz. Ela é reatribuída ref
para fazer referência ao último elemento de matriz.
Você pode definir uma variável local ref readonly
. Você não pode atribuir um valor a uma variável ref readonly
. No entanto, você pode reatribuir ref
essa variável de referência, como mostra o exemplo a seguir:
int[] xs = [1, 2, 3];
ref readonly int element = ref xs[0];
// element = 100; error CS0131: The left-hand side of an assignment must be a variable, property or indexer
Console.WriteLine(element); // output: 1
element = ref xs[^1];
Console.WriteLine(element); // output: 3
Você pode atribuir um retorno de referência a uma variável de referência, como mostra o exemplo a seguir:
using System;
public class NumberStore
{
private readonly int[] numbers = [1, 30, 7, 1557, 381, 63, 1027, 2550, 511, 1023];
public ref int GetReferenceToMax()
{
ref int max = ref numbers[0];
for (int i = 1; i < numbers.Length; i++)
{
if (numbers[i] > max)
{
max = ref numbers[i];
}
}
return ref max;
}
public override string ToString() => string.Join(" ", numbers);
}
public static class ReferenceReturnExample
{
public static void Run()
{
var store = new NumberStore();
Console.WriteLine($"Original sequence: {store.ToString()}");
ref int max = ref store.GetReferenceToMax();
max = 0;
Console.WriteLine($"Updated sequence: {store.ToString()}");
// Output:
// Original sequence: 1 30 7 1557 381 63 1027 2550 511 1023
// Updated sequence: 1 30 7 1557 381 63 1027 0 511 1023
}
}
No exemplo anterior, o método GetReferenceToMax
é um método returns-by-ref. Ele não retorna o valor máximo em si, mas um retorno de referência que é um alias para o elemento de matriz que contém o valor máximo. O método Run
atribui um retorno de referência à variável de referência max
. Em seguida, atribuindo a max
, ele atualiza o armazenamento interno da instância store
. Você também pode definir um método ref readonly
. Os chamadores de um método ref readonly
não podem atribuir um valor ao seu retorno de referência.
A variável de iteração da instrução foreach
pode ser uma variável de referência. Para obter mais informações, consulte a seção sobre a instrução foreach
do artigo Instruções de iteração.
Em cenários críticos de desempenho, o uso de variáveis de referência e retornos pode aumentar o desempenho evitando operações de cópia potencialmente caras.
O compilador garante que uma variável de referência não sobreviva ao seu referenciador e permaneça válida durante todo o tempo de vida. Para saber mais, confira a seção Contextos seguros de referência da Especificação da linguagem C#.
Para obter informações sobre os campos ref
, confira a seção ref
campos do artigo ref
tipos de estrutura.
ref com escopo
A palavra-chave contextual scoped
restringe o tempo de vida de um valor. O modificador scoped
restringe o tempo de vida ref-safe-to-escape ou safe-to-escape, respectivamente, ao método atual. Efetivamente, adicionar o modificador scoped
declara que seu código não estenderá o tempo de vida da variável.
Você pode aplicar scoped
a um parâmetro ou variável local. O modificador scoped
pode ser aplicado a parâmetros e locais quando o tipo for um ref struct
. Caso contrário, o modificador scoped
poderá ser aplicado somente a variáveis de referência locais. Isso inclui variáveis locais declaradas com o modificador ref
e os parâmetros declarados com os modificadores in
, ref
ou out
.
O modificador scoped
é adicionado implicitamente a this
em métodos declarados em parâmetros struct
, out
e ref
quando o tipo for um ref struct
.
Especificação da linguagem C#
Para obter mais informações, confira as seguintes seções da especificação da linguagem C#:
Para obter mais informações sobre o modificador scoped
, consulte a nota de proposta Aprimoramentos de struct de baixo nível.