Partilhar via


Operadores de atribuição (referência C#)

O operador = de atribuição atribui o valor de seu operando direito a uma variável, uma propriedade ou um elemento indexador dado por seu operando esquerdo. O resultado de uma expressão de atribuição é o valor atribuído ao operando esquerdo. O tipo do operando direito deve ser o mesmo que o tipo do operando esquerdo ou implicitamente conversível para ele.

O operador = de atribuição é de associação à direita, ou seja, uma expressão da forma

a = b = c

É avaliado como

a = (b = c)

O exemplo a seguir demonstra o uso do operador de atribuição com uma variável local, uma propriedade e um elemento indexador como seu operando esquerdo:

List<double> numbers = [1.0, 2.0, 3.0];

Console.WriteLine(numbers.Capacity);
numbers.Capacity = 100;
Console.WriteLine(numbers.Capacity);
// Output:
// 4
// 100

int newFirstElement;
double originalFirstElement = numbers[0];
newFirstElement = 5;
numbers[0] = newFirstElement;
Console.WriteLine(originalFirstElement);
Console.WriteLine(numbers[0]);
// Output:
// 1
// 5

O operando esquerdo de uma atribuição recebe o valor do operando direito. Quando os operandos são de tipos de valor, a atribuição copia o conteúdo do operando à direita. Quando os operandos são de tipos de referência, a atribuição copia a referência ao objeto.

Esta operação é chamada atribuição de valor: o valor é atribuído.

A partir do C# 14, o lado esquerdo de uma atribuição de valor pode incluir uma expressão de membro condicional nula, como ?. ou ?[]. Se o lado esquerdo for nulo, a expressão do lado direito não será avaliada.

Atribuição de ref

A atribuição de referência= ref faz com que o seu operando esquerdo se torne um alias para o operando direito, como demonstra o exemplo a seguir:

void Display(double[] s) => Console.WriteLine(string.Join(" ", s));

double[] arr = { 0.0, 0.0, 0.0 };
Display(arr);

ref double arrayElement = ref arr[0];
arrayElement = 3.0;
Display(arr);

arrayElement = ref arr[arr.Length - 1];
arrayElement = 5.0;
Display(arr);
// Output:
// 0 0 0
// 3 0 0
// 3 0 5

No exemplo anterior, a variávelarrayElement de referência local é inicializada como um alias para o primeiro elemento de matriz. Em seguida, ele é ref reatribuído para se referir ao último elemento da matriz. Como é um alias, quando você atualiza seu valor com um operador =de atribuição comum, o elemento de matriz correspondente também é atualizado.

O operando esquerdo de ref atribuição pode ser uma variável de referência local, um ref campo, e um parâmetro de método ref, out, ou in. Ambos os operandos devem ser do mesmo tipo.

Uma atribuição ref significa que uma variável de referência tem uma referência diferente. Não está mais se referindo ao seu referente anterior. Usar ref = em um parâmetro ref significa que o parâmetro não se refere mais ao seu argumento. Todas as ações que modificam o estado do objeto depois de ref reatribuí-lo fazem essas modificações no novo item. Por exemplo, considere o seguinte método:

private static void RefReassignAndModify(scoped ref string s)
{
    string sLocal = "Hello";
    Console.WriteLine(sLocal);  // Output: Hello

    s = ref sLocal;
    s = "World";
    Console.WriteLine(s);  // Output: World

O uso a seguir mostra que a atribuição ao parâmetro s não é visível após a chamada de método porque s foi ref reatribuído para se referir a sLocal antes da cadeia de caracteres ser modificada:

string msg = "Hi";
RefReassignAndModify(ref msg);
Console.WriteLine(msg); // Output: Hi!

Atribuição composta

Para um operador binário op, uma expressão de atribuição composta na forma de

x op= y

É equivalente a

x = x op y

Só que x só é avaliada uma vez.

Os operadores aritméticos, lógicos booleanos, lógicos bitwise e de deslocamento suportam a atribuição composta.

Atribuição de coalescência nula

Você pode usar o operador ??= de atribuição de coalescência nula para atribuir o valor de seu operando direito ao operando esquerdo somente se o operando esquerdo for avaliado como null. Para obter mais informações, consulte o artigo ?? e ??= operadores.

Capacidade de sobrecarga do operador

Um tipo definido pelo usuário não pode sobrecarregar o operador de atribuição. No entanto, um tipo definido pelo usuário pode definir uma conversão implícita para outro tipo. Dessa forma, o valor de um tipo definido pelo usuário pode ser atribuído a uma variável, uma propriedade ou um elemento indexador de outro tipo. Para obter mais informações, consulte Operadores de conversão definidos pelo usuário.

Se um tipo definido pelo usuário sobrecarrega um operador opbinário, o op= operador, se existir, também é implicitamente sobrecarregado. A partir do C# 14, um tipo definido pelo usuário pode sobrecarregar explicitamente os operadores de atribuição compostos (op=) para fornecer uma implementação mais eficiente. Normalmente, um tipo sobrecarrega esses operadores porque o valor pode ser atualizado no local, em vez de alocar uma nova instância para armazenar o resultado da operação binária. Se um tipo não fornecer uma sobrecarga explícita, o compilador gerará a sobrecarga implícita.

Especificação da linguagem C#

Para obter mais informações, consulte a seção Operadores de atribuição da especificação da linguagem C# e a especificação do recurso de atribuição composta definida pelo usuário .

Consulte também