Operadores de acesso de membro e expressões (referência C#)Member access operators and expressions (C# reference)

Você pode usar os seguintes operadores e expressões ao acessar um membro de tipo:You can use the following operators and expressions when you access a type member:

Expressão de acesso de membro.Member access expression .

Use o token . para acessar um membro de um namespace ou um tipo, como demonstram os exemplos a seguir:You use the . token to access a member of a namespace or a type, as the following examples demonstrate:

  • Use . para acessar um namespace aninhado em um namespace, como mostra o exemplo a seguir de uma using diretiva :Use . to access a nested namespace within a namespace, as the following example of a using directive shows:

    using System.Collections.Generic;
    
  • Use . para formar um nome qualificado para acessar um tipo dentro de um namespace, como mostra o código a seguir:Use . to form a qualified name to access a type within a namespace, as the following code shows:

    System.Collections.Generic.IEnumerable<int> numbers = new int[] { 1, 2, 3 };
    

    Use uma using diretiva para tornar o uso de nomes qualificados opcional.Use a using directive to make the use of qualified names optional.

  • Use . para acessar membros de tipo, estático e não-estático, como mostra o código a seguir:Use . to access type members, static and non-static, as the following code shows:

    var constants = new List<double>();
    constants.Add(Math.PI);
    constants.Add(Math.E);
    Console.WriteLine($"{constants.Count} values to show:");
    Console.WriteLine(string.Join(", ", constants));
    // Output:
    // 2 values to show:
    // 3.14159265358979, 2.71828182845905
    

Você também pode usar . para acessar um método de extensão.You can also use . to access an extension method.

Operador de indexador []Indexer operator []

Os colchetes, [], normalmente são usados para acesso de elemento de matriz, indexador ou ponteiro.Square brackets, [], are typically used for array, indexer, or pointer element access.

Acesso de matrizArray access

O exemplo a seguir demonstra como acessar elementos de matriz:The following example demonstrates how to access array elements:

int[] fib = new int[10];
fib[0] = fib[1] = 1;
for (int i = 2; i < fib.Length; i++)
{
    fib[i] = fib[i - 1] + fib[i - 2];
}
Console.WriteLine(fib[fib.Length - 1]);  // output: 55

double[,] matrix = new double[2,2];
matrix[0,0] = 1.0;
matrix[0,1] = 2.0;
matrix[1,0] = matrix[1,1] = 3.0;
var determinant = matrix[0,0] * matrix[1,1] - matrix[1,0] * matrix[0,1];
Console.WriteLine(determinant);  // output: -3

Se um índice de matriz estiver fora dos limites da dimensão correspondente de uma matriz, uma IndexOutOfRangeException será gerada.If an array index is outside the bounds of the corresponding dimension of an array, an IndexOutOfRangeException is thrown.

Como mostra o exemplo anterior, você também usar colchetes quando declara um tipo de matriz ou instancia uma instância de matriz.As the preceding example shows, you also use square brackets when you declare an array type or instantiate an array instance.

Para obter mais informações sobre matrizes, confira Matrizes.For more information about arrays, see Arrays.

Acesso de indexadorIndexer access

O exemplo a seguir usa o Dictionary<TKey,TValue> tipo .net para demonstrar o acesso ao indexador:The following example uses the .NET Dictionary<TKey,TValue> type to demonstrate indexer access:

var dict = new Dictionary<string, double>();
dict["one"] = 1;
dict["pi"] = Math.PI;
Console.WriteLine(dict["one"] + dict["pi"]);  // output: 4.14159265358979

Os indexadores permitem indexar instâncias de um tipo definido pelo usuário de maneira semelhante à indexação de matriz.Indexers allow you to index instances of a user-defined type in the similar way as array indexing. Ao contrário dos índices de matriz, que devem ser inteiros, os parâmetros do indexador podem ser declarados como sendo de qualquer tipo.Unlike array indices, which must be integer, the indexer parameters can be declared to be of any type.

Para obter mais informações sobre indexadores, confira Indexadores.For more information about indexers, see Indexers.

Outros usos de []Other usages of []

Para saber mais sobre o acesso a elemento de ponteiro, confira a seção Operador de acesso a elemento de ponteiro [] do artigo Operadores relacionados a ponteiro.For information about pointer element access, see the Pointer element access operator [] section of the Pointer related operators article.

Os colchetes também são usados para especificar atributos:You also use square brackets to specify attributes:

[System.Diagnostics.Conditional("DEBUG")]
void TraceMethod() {}

Operadores condicionais nulos ?.Null-conditional operators ?. e ?[]and ?[]

Disponível no C# 6 e posterior, um operador NULL-Conditional aplica um acesso de membro, ?. ou acesso de elemento, ?[] , operação para seu operando somente se esse operando for avaliado como não nulo; caso contrário, retornará null .Available in C# 6 and later, a null-conditional operator applies a member access, ?., or element access, ?[], operation to its operand only if that operand evaluates to non-null; otherwise, it returns null. Isto éThat is,

  • Se for a avaliada como null , o resultado de a?.x ou a?[x] é null .If a evaluates to null, the result of a?.x or a?[x] is null.

  • Se for a avaliada como não nula, o resultado a?.x ou a?[x] será o mesmo que o resultado de a.x ou a[x] , respectivamente.If a evaluates to non-null, the result of a?.x or a?[x] is the same as the result of a.x or a[x], respectively.

    Observação

    Se a.x ou a[x] lançar uma exceção, a?.x ou a?[x] geraria a mesma exceção para não NULL a .If a.x or a[x] throws an exception, a?.x or a?[x] would throw the same exception for non-null a. Por exemplo, se a for uma instância de matriz não nula e x estiver fora dos limites de a , o a?[x] geraria um IndexOutOfRangeException .For example, if a is a non-null array instance and x is outside the bounds of a, a?[x] would throw an IndexOutOfRangeException.

Os operadores condicionais nulos estão entrando em curto-circuito.The null-conditional operators are short-circuiting. Ou seja, se uma operação em uma cadeia de membro operações condicionais de acesso a membro ou elemento retornar null, o restante da cadeia não será executado.That is, if one operation in a chain of conditional member or element access operations returns null, the rest of the chain doesn't execute. No exemplo a seguir, B não será avaliado se A for avaliado como null e C não será avaliado se A ou B for avaliado como null:In the following example, B is not evaluated if A evaluates to null and C is not evaluated if A or B evaluates to null:

A?.B?.Do(C);
A?.B?[C];

O exemplo a seguir demonstra o uso dos operadores ?. e ?[]:The following example demonstrates the usage of the ?. and ?[] operators:

double SumNumbers(List<double[]> setsOfNumbers, int indexOfSetToSum)
{
    return setsOfNumbers?[indexOfSetToSum]?.Sum() ?? double.NaN;
}

var sum1 = SumNumbers(null, 0);
Console.WriteLine(sum1);  // output: NaN

var numberSets = new List<double[]>
{
    new[] { 1.0, 2.0, 3.0 },
    null
};

var sum2 = SumNumbers(numberSets, 0);
Console.WriteLine(sum2);  // output: 6

var sum3 = SumNumbers(numberSets, 1);
Console.WriteLine(sum3);  // output: NaN

O exemplo anterior também usa o operador ?? de União nulo para especificar uma expressão alternativa a ser avaliada, caso o resultado de uma operação condicional nula seja null .The preceding example also uses the null-coalescing operator ?? to specify an alternative expression to evaluate in case the result of a null-conditional operation is null.

Se a.x ou a[x] for de um tipo de valor não anulável T a?.x ou a?[x] for do tipo de valor anulável correspondente T? .If a.x or a[x] is of a non-nullable value type T, a?.x or a?[x] is of the corresponding nullable value type T?. Se você precisar de uma expressão do tipo T , aplique o operador de União nula ?? a uma expressão condicional nula, como mostra o exemplo a seguir:If you need an expression of type T, apply the null-coalescing operator ?? to a null-conditional expression, as the following example shows:

int GetSumOfFirstTwoOrDefault(int[] numbers)
{
    if ((numbers?.Length ?? 0) < 2)
    {
        return 0;
    }
    return numbers[0] + numbers[1];
}

Console.WriteLine(GetSumOfFirstTwoOrDefault(null));  // output: 0
Console.WriteLine(GetSumOfFirstTwoOrDefault(new int[0]));  // output: 0
Console.WriteLine(GetSumOfFirstTwoOrDefault(new[] { 3, 4, 5 }));  // output: 7

No exemplo anterior, se você não usar o ?? operador, o numbers?.Length < 2 será avaliado como false quando numbers é null .In the preceding example, if you don't use the ?? operator, numbers?.Length < 2 evaluates to false when numbers is null.

O operador de acesso do membro condicional nulo ?. também é conhecido como o operador Elvis.The null-conditional member access operator ?. is also known as the Elvis operator.

Invocação de delegado thread-safeThread-safe delegate invocation

Use o operador ?. para verificar se um delegado é não nulo e chame-o de uma forma thread-safe (por exemplo, quando você aciona um evento), conforme mostrado no código a seguir:Use the ?. operator to check if a delegate is non-null and invoke it in a thread-safe way (for example, when you raise an event), as the following code shows:

PropertyChanged?.Invoke(…)

Esse código é equivalente ao código a seguir que você usaria no C# 5 ou anterior:That code is equivalent to the following code that you would use in C# 5 or earlier:

var handler = this.PropertyChanged;
if (handler != null)
{
    handler(…);
}

Essa é uma forma thread-safe de garantir que apenas um não nulo handler seja invocado.That is a thread-safe way to ensure that only a non-null handler is invoked. Como as instâncias de delegado são imutáveis, nenhum thread pode alterar o objeto referenciado pela handler variável local.Because delegate instances are immutable, no thread can change the object referenced by the handler local variable. Em particular, se o código executado por outro thread cancelar a assinatura do PropertyChanged evento e PropertyChanged se tornar null antes de handler ser invocado, o objeto referenciado por handler permanecerá inalterado.In particular, if the code executed by another thread unsubscribes from the PropertyChanged event and PropertyChanged becomes null before handler is invoked, the object referenced by handler remains unaffected. O ?. operador avalia seu operando à esquerda não mais de uma vez, garantindo que ele não possa ser alterado para null depois de ser verificado como não nulo.The ?. operator evaluates its left-hand operand no more than once, guaranteeing that it cannot be changed to null after being verified as non-null.

Expressão de invocação ()Invocation expression ()

Use parênteses, (), para chamar um método ou invocar um delegado.Use parentheses, (), to call a method or invoke a delegate.

O exemplo a seguir demonstra como chamar um método (com ou sem argumentos) e invocar um delegado:The following example demonstrates how to call a method, with or without arguments, and invoke a delegate:

Action<int> display = s => Console.WriteLine(s);

var numbers = new List<int>();
numbers.Add(10);
numbers.Add(17);
display(numbers.Count);   // output: 2

numbers.Clear();
display(numbers.Count);   // output: 0

Você também pode usar parênteses ao invocar um construtor com o operador new.You also use parentheses when you invoke a constructor with the new operator.

Outros usos de ()Other usages of ()

Você também pode usar parênteses para ajustar a ordem na qual as operações em uma expressão são avaliadas.You also use parentheses to adjust the order in which to evaluate operations in an expression. Para saber mais, confira Operadores C#.For more information, see C# operators.

Expressões de conversão, que executam conversões de tipo explícitas, também usam parênteses.Cast expressions, which perform explicit type conversions, also use parentheses.

Índice do operador end ^Index from end operator ^

Disponível em C# 8,0 e posterior, o ^ operador indica a posição do elemento do final de uma sequência.Available in C# 8.0 and later, the ^ operator indicates the element position from the end of a sequence. Para uma sequência de comprimento length , ^n aponta para o elemento com offset length - n do início de uma sequência.For a sequence of length length, ^n points to the element with offset length - n from the start of a sequence. Por exemplo, ^1 aponta para o último elemento de uma sequência e ^length aponta para o primeiro elemento de uma sequência.For example, ^1 points to the last element of a sequence and ^length points to the first element of a sequence.

int[] xs = new[] { 0, 10, 20, 30, 40 };
int last = xs[^1];
Console.WriteLine(last);  // output: 40

var lines = new List<string> { "one", "two", "three", "four" };
string prelast = lines[^2];
Console.WriteLine(prelast);  // output: three

string word = "Twenty";
Index toFirst = ^word.Length;
char first = word[toFirst];
Console.WriteLine(first);  // output: T

Como mostra o exemplo anterior, Expression ^e é do System.Index tipo.As the preceding example shows, expression ^e is of the System.Index type. Na expressão ^e , o resultado de e deve ser implicitamente conversível para int .In expression ^e, the result of e must be implicitly convertible to int.

Você também pode usar o ^ operador com o operador Range para criar um intervalo de índices.You can also use the ^ operator with the range operator to create a range of indices. Para obter mais informações, consulte índices e intervalos.For more information, see Indices and ranges.

Operador de intervalo..Range operator ..

Disponível em C# 8,0 e posterior, o .. operador especifica o início e o término de um intervalo de índices como operandos.Available in C# 8.0 and later, the .. operator specifies the start and end of a range of indices as its operands. O operando à esquerda é um início inclusivo de um intervalo.The left-hand operand is an inclusive start of a range. O operando de lado direito é uma extremidade exclusiva de um intervalo.The right-hand operand is an exclusive end of a range. Qualquer um dos operandos pode ser um índice do início ou do final de uma sequência, como mostra o exemplo a seguir:Either of operands can be an index from the start or from the end of a sequence, as the following example shows:

int[] numbers = new[] { 0, 10, 20, 30, 40, 50 };
int start = 1;
int amountToTake = 3;
int[] subset = numbers[start..(start + amountToTake)];
Display(subset);  // output: 10 20 30

int margin = 1;
int[] inner = numbers[margin..^margin];
Display(inner);  // output: 10 20 30 40

string line = "one two three";
int amountToTakeFromEnd = 5;
Range endIndices = ^amountToTakeFromEnd..^0;
string end = line[endIndices];
Console.WriteLine(end);  // output: three

void Display<T>(IEnumerable<T> xs) => Console.WriteLine(string.Join(" ", xs));

Como mostra o exemplo anterior, Expression a..b é do System.Range tipo.As the preceding example shows, expression a..b is of the System.Range type. Na expressão a..b , os resultados de a e b devem ser conversíveis implicitamente para int ou Index .In expression a..b, the results of a and b must be implicitly convertible to int or Index.

Você pode omitir qualquer um dos operandos do .. operador para obter um intervalo aberto:You can omit any of the operands of the .. operator to obtain an open-ended range:

  • a.. equivale a a..^0a.. is equivalent to a..^0
  • ..b equivale a 0..b..b is equivalent to 0..b
  • .. equivale a 0..^0.. is equivalent to 0..^0
int[] numbers = new[] { 0, 10, 20, 30, 40, 50 };
int amountToDrop = numbers.Length / 2;

int[] rightHalf = numbers[amountToDrop..];
Display(rightHalf);  // output: 30 40 50

int[] leftHalf = numbers[..^amountToDrop];
Display(leftHalf);  // output: 0 10 20

int[] all = numbers[..];
Display(all);  // output: 0 10 20 30 40 50

void Display<T>(IEnumerable<T> xs) => Console.WriteLine(string.Join(" ", xs));

Para obter mais informações, consulte índices e intervalos.For more information, see Indices and ranges.

Capacidade de sobrecarga do operadorOperator overloadability

Os . () operadores,, ^ e .. não podem ser sobrecarregados.The ., (), ^, and .. operators cannot be overloaded. O operador [] também é considerado um operador não sobrecarregável.The [] operator is also considered a non-overloadable operator. Use indexadores para permitir a indexação com tipos definidos pelo usuário.Use indexers to support indexing with user-defined types.

Especificação da linguagem C#C# language specification

Para obter mais informações, confira as seguintes seções da especificação da linguagem C#:For more information, see the following sections of the C# language specification:

Para obter mais informações sobre índices e intervalos, consulte a Nota de proposta de recurso.For more information about indices and ranges, see the feature proposal note.

Confira tambémSee also