Opérateurs et expressions d’accès aux membres (référence C#)Member access operators and expressions (C# reference)

Vous pouvez utiliser les opérateurs et expressions suivants lorsque vous accédez à un membre de type :You can use the following operators and expressions when you access a type member:

Expression d’accès au membre.Member access expression .

Le jeton . sert à accéder à l’un des membres d’un espace de noms ou d’un type, comme le montrent les exemples suivants :You use the . token to access a member of a namespace or a type, as the following examples demonstrate:

  • Utilisez . pour accéder à un espace de noms imbriqué dans un espace de noms, comme le montre l’exemple suivant d’une using directive :Use . to access a nested namespace within a namespace, as the following example of a using directive shows:

    using System.Collections.Generic;
    
  • Utilisez . pour former un nom qualifié permettant d’accéder à un type dans un espace de noms, comme le montre le code suivant :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 };
    

    Utilisez une using directive pour rendre l’utilisation des noms qualifiés facultative.Use a using directive to make the use of qualified names optional.

  • Utilisez . pour accéder aux membres de type, statiques et non statiques, comme le montre le code suivant :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
    

Vous pouvez également utiliser . pour accéder à une méthode d’extension.You can also use . to access an extension method.

Opérateur d’indexeur []Indexer operator []

Les crochets, [], sont généralement utilisés pour l’accès à un élément tableau, indexeur ou pointeur.Square brackets, [], are typically used for array, indexer, or pointer element access.

Accès aux tableauxArray access

L’exemple suivant montre comment accéder à des éléments tableau :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

Si un index de tableau est en dehors des limites de la dimension correspondante d’un tableau, une IndexOutOfRangeException est levée.If an array index is outside the bounds of the corresponding dimension of an array, an IndexOutOfRangeException is thrown.

Comme le montre l’exemple précédent, vous utilisez également des crochets quand vous déclarez un type tableau ou instanciez une instance de tableau.As the preceding example shows, you also use square brackets when you declare an array type or instantiate an array instance.

Pour plus d’informations sur les tableaux, consultez Tableaux.For more information about arrays, see Arrays.

Accès aux indexeursIndexer access

L’exemple suivant utilise le Dictionary<TKey,TValue> type .net pour illustrer l’accès à l’indexeur :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

Les indexeurs vous permettent d’indexer des instances d’un type défini par l’utilisateur en procédant de la même façon que pour l’indexation de tableau.Indexers allow you to index instances of a user-defined type in the similar way as array indexing. Contrairement aux index de tableau, qui doivent être des entiers, les paramètres de l’indexeur peuvent être déclarés comme n’importe quel type.Unlike array indices, which must be integer, the indexer parameters can be declared to be of any type.

Pour plus d’informations sur les indexeurs, consultez Indexeurs.For more information about indexers, see Indexers.

Autres utilisations de []Other usages of []

Pour plus d’informations concernant l’accès à l’élément de pointeur, consultez la section Opérateur d’accès à l’élément de pointeur [] de l’article Opérateurs associés au pointeur.For information about pointer element access, see the Pointer element access operator [] section of the Pointer related operators article.

Vous utilisez également des crochets pour spécifier des attributs :You also use square brackets to specify attributes:

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

Opérateurs conditionnels Null ?.Null-conditional operators ?. et ?[]and ?[]

Disponible en C# 6 et versions ultérieures, un opérateur conditionnel null applique un accès de membre, ?. ou d’accès à l' élément, ?[] , à son opérande uniquement si cet opérande a la valeur non NULL ; sinon, il retourne 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. C'estThat is,

  • Si a prend la valeur null , le résultat de a?.x ou a?[x] est null .If a evaluates to null, the result of a?.x or a?[x] is null.

  • Si a prend la valeur non null, le résultat de a?.x ou a?[x] est le même que le résultat de a.x ou a[x] , respectivement.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.

    Notes

    Si a.x ou a[x] lèvent une exception, a?.x ou a?[x] lèvent la même exception pour la valeur non 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. Par exemple, si a est une instance de tableau non null et x se trouve en dehors des limites de a , a?[x] lèvera un 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.

Les opérateurs conditionnels Null ont un effet de court-circuit.The null-conditional operators are short-circuiting. Autrement dit, si une opération dans une chaîne d’opérations d’accès au membre ou à l’élément conditionnelles retourne une valeur null, le reste de la chaîne ne s’exécute pas.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. Dans l’exemple suivant, B n’est pas évalué si A prend la valeur null et C n’est pas évalué si A ou B prend la valeur 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];

L’exemple suivant illustre l’utilisation des opérateurs ?. et ?[] :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

L’exemple précédent utilise également l' opérateur ?? de fusion Null pour spécifier une autre expression à évaluer si le résultat d’une opération conditionnelle null est 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.

Si a.x ou a[x] est un type valeur n’acceptant pas T les valeurs NULL, a?.x ou a?[x] est du type valeur Nullable correspondant 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?. Si vous avez besoin d’une expression de type T , appliquez l’opérateur de fusion Null ?? à une expression conditionnelle null, comme le montre l’exemple suivant :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

Dans l’exemple précédent, si vous n’utilisez pas l' ?? opérateur, numbers?.Length < 2 prend la valeur false lorsque numbers est null .In the preceding example, if you don't use the ?? operator, numbers?.Length < 2 evaluates to false when numbers is null.

L’opérateur d’accès aux membres conditionnels null ?. est également appelé l’opérateur Elvis.The null-conditional member access operator ?. is also known as the Elvis operator.

Appel de délégué thread-safeThread-safe delegate invocation

Utilisez l’opérateur ?. pour vérifier si un délégué est non Null et l’appeler de manière thread-safe (par exemple, quand vous déclenchez un événement), comme illustré dans le code suivant :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(…)

Ce code est équivalent au code suivant que vous utiliseriez dans C# 5 ou une version antérieure :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(…);
}

C’est une façon thread-safe de s’assurer que seule une valeur non null handler est appelée.That is a thread-safe way to ensure that only a non-null handler is invoked. Étant donné que les instances de délégué sont immuables, aucun thread ne peut modifier l’objet référencé par la handler variable locale.Because delegate instances are immutable, no thread can change the object referenced by the handler local variable. En particulier, si le code exécuté par un autre thread annule son abonnement à l' PropertyChanged événement et PropertyChanged devient null avant l’appel de handler , l’objet référencé par handler reste inchangé.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. L' ?. opérateur évalue son opérande de gauche un peu plus d’une fois, ce qui garantit qu’il ne peut pas être modifié null après avoir été vérifié comme non null.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.

Expression d’appel ()Invocation expression ()

Utilisez des parenthèses, (), pour appeler une méthode ou un délégué.Use parentheses, (), to call a method or invoke a delegate.

L’exemple suivant montre comment appeler une méthode, avec ou sans arguments, et un délégué :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

Vous utilisez également des parenthèses quand vous appelez un constructeur avec l’opérateur new.You also use parentheses when you invoke a constructor with the new operator.

Autres utilisations de ()Other usages of ()

Vous utilisez également des parenthèses pour ajuster l’ordre dans lequel évaluer les opérations dans une expression.You also use parentheses to adjust the order in which to evaluate operations in an expression. Pour plus d’informations, consultez Opérateurs C#.For more information, see C# operators.

Les expressions cast, qui effectuent des conversions de type explicites, utilisent aussi des parenthèses.Cast expressions, which perform explicit type conversions, also use parentheses.

Index de fin d’opérateur ^Index from end operator ^

Disponible en C# 8,0 et versions ultérieures, l' ^ opérateur indique la position de l’élément à partir de la fin d’une séquence.Available in C# 8.0 and later, the ^ operator indicates the element position from the end of a sequence. Pour une séquence de longueur length , ^n pointe vers l’élément avec décalage length - n à partir du début d’une séquence.For a sequence of length length, ^n points to the element with offset length - n from the start of a sequence. Par exemple, ^1 pointe vers le dernier élément d’une séquence et ^length pointe vers le premier élément d’une séquence.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

Comme le montre l’exemple précédent, expression ^e est du System.Index type.As the preceding example shows, expression ^e is of the System.Index type. Dans Expression ^e , le résultat de e doit être implicitement convertible en int .In expression ^e, the result of e must be implicitly convertible to int.

Vous pouvez également utiliser l' ^ opérateur avec l' opérateur Range pour créer une plage d’index.You can also use the ^ operator with the range operator to create a range of indices. Pour plus d’informations, consultez index et plages.For more information, see Indices and ranges.

Opérateur de plage..Range operator ..

Disponible en C# 8,0 et versions ultérieures, l' .. opérateur spécifie le début et la fin d’une plage d’index comme opérandes.Available in C# 8.0 and later, the .. operator specifies the start and end of a range of indices as its operands. L’opérande de gauche est un début inclusif d’une plage.The left-hand operand is an inclusive start of a range. L’opérande de droite est une extrémité exclusive d’une plage.The right-hand operand is an exclusive end of a range. L’un ou l’autre des opérandes peut être un index à partir du début ou de la fin d’une séquence, comme le montre l’exemple suivant :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));

Comme le montre l’exemple précédent, expression a..b est du System.Range type.As the preceding example shows, expression a..b is of the System.Range type. Dans Expression a..b , les résultats de a et b doivent être implicitement convertibles en int ou Index .In expression a..b, the results of a and b must be implicitly convertible to int or Index.

Vous pouvez omettre l’un des opérandes de l' .. opérateur pour obtenir une plage ouverte :You can omit any of the operands of the .. operator to obtain an open-ended range:

  • a.. équivaut à a..^0a.. is equivalent to a..^0
  • ..b équivaut à 0..b..b is equivalent to 0..b
  • .. équivaut à 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));

Pour plus d’informations, consultez index et plages.For more information, see Indices and ranges.

Capacité de surcharge de l’opérateurOperator overloadability

Les . opérateurs,, () ^ et .. ne peuvent pas être surchargés.The ., (), ^, and .. operators cannot be overloaded. L’opérateur [] est également considéré comme un opérateur non surchargeable.The [] operator is also considered a non-overloadable operator. Utilisez des indexeurs pour prendre en charge l’indexation avec des types définis par l’utilisateur.Use indexers to support indexing with user-defined types.

spécification du langage C#C# language specification

Pour plus d’informations, consultez les sections suivantes de la spécification du langage C# :For more information, see the following sections of the C# language specification:

Pour plus d’informations sur les index et les plages, consultez la Remarque relativeà la proposition de fonctionnalité.For more information about indices and ranges, see the feature proposal note.

Voir aussiSee also