Tableaux

Vous pouvez stocker plusieurs variables du même type dans une structure de données de type tableau. Vous déclarez un tableau en spécifiant le type de ses éléments. Si vous souhaitez que le tableau stocke des éléments de n’importe quel type, vous pouvez spécifier object comme type. Dans le système de type unifié de C#, tous les types (les types référence et valeur, prédéfinis ou définis par l’utilisateur) héritent directement ou indirectement du type Object.

type[] arrayName;

Un tableau possède les propriétés suivantes :

  • Un tableau peut être unidimensionnel, multidimensionnel ou en escalier.
  • Le nombre de dimensions est défini lorsqu’une variable de tableau est déclarée. La longueur de chaque dimension est établie lors de la création de l’instance de tableau. Ces valeurs ne peuvent pas être modifiées pendant la durée de vie de l’instance.
  • Un tableau en escalier est un tableau de tableaux, et chaque tableau membre a la valeur null par défaut.
  • Les tableaux sont indexés sur zéro : un tableau avec n éléments est indexée de 0 à n-1.
  • Les éléments de tableau peuvent être de n’importe quel type, y compris un type tableau.
  • Les types tableau sont des types référence dérivés du type de base abstrait Array. Tous les tableaux implémentent IList et IEnumerable. Vous pouvez utiliser l’instruction foreach pour itérer au sein d’un tableau. Les tableaux unidimensionnels implémentent aussi IList<T> et IEnumerable<T>.

Les éléments d’un tableau peuvent être initialisés sur des valeurs connues lors de la création du tableau. À compter de C# 12, tous les types de collection peuvent être initialisés à l’aide d’une expression de collection. Les éléments qui ne sont pas initialisés sont définis sur la valeur par défaut. La valeur par défaut est le modèle 0 bits. Tous les types de référence (y compris les types non-nullables) ont les valeurs null. Tous les types de valeur ont les modèles 0 bits. Cela signifie que la propriété Nullable<T>.HasValue est false et que la propriété Nullable<T>.Value n’est pas définie. Dans l’implémentation .NET, la propriété Value lève une exception.

L’exemple suivant crée des tableaux unidimensionnels, multidimensionnels et en escalier :

// Declare a single-dimensional array of 5 integers.
int[] array1 = new int[5];

// Declare and set array element values.
int[] array2 = [1, 2, 3, 4, 5, 6];

// Declare a two dimensional array.
int[,] multiDimensionalArray1 = new int[2, 3];

// Declare and set array element values.
int[,] multiDimensionalArray2 = { { 1, 2, 3 }, { 4, 5, 6 } };

// Declare a jagged array.
int[][] jaggedArray = new int[6][];

// Set the values of the first array in the jagged array structure.
jaggedArray[0] = [1, 2, 3, 4];

Tableaux unidimensionnels

Un tableau unidimensionnel est une séquence d’éléments similaires. Vous accédez à un élément via son index. L’index est sa position ordinale dans la séquence. Le premier élément du tableau est à l’index 0. Vous créez un tableau unidimensionnel à l’aide du nouvel opérateur en spécifiant le type d’élément du tableau et le nombre d’éléments. L’exemple suivant déclare et initialise des tableaux unidimensionnels :

int[] array = new int[5];
string[] weekDays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];

Console.WriteLine(weekDays[0]);
Console.WriteLine(weekDays[1]);
Console.WriteLine(weekDays[2]);
Console.WriteLine(weekDays[3]);
Console.WriteLine(weekDays[4]);
Console.WriteLine(weekDays[5]);
Console.WriteLine(weekDays[6]);

/*Output:
Sun
Mon
Tue
Wed
Thu
Fri
Sat
*/

La première déclaration déclare un tableau non initialisé de cinq entiers, de array[0] à array[4]. Les éléments du tableau sont initialisés à la valeur par défaut du type d’élément, 0 pour les entiers. La deuxième déclaration déclare un tableau de chaînes et initialise les sept valeurs de ce tableau. Une série d’instructions Console.WriteLine imprime tous les éléments du tableau weekDay. Pour les tableaux unidimensionnels, l’instruction foreach traite les éléments dans l’ordre croissant des index, en commençant par l’index 0 et en terminant par l’index Length - 1.

Passer des tableaux unidimensionnels en tant qu’arguments

Vous pouvez passer un tableau unidimensionnel initialisé à une méthode. Dans l’exemple suivant, un tableau de chaînes est initialisé et passé en tant qu’argument à une méthode DisplayArray pour des chaînes. La méthode affiche les éléments du tableau. Ensuite, la méthode ChangeArray inverse les éléments du tableau, puis la méthode ChangeArrayElements modifie les trois premiers éléments du tableau. Une fois que chaque méthode est retournée, la méthode DisplayArray montre que le passage d’un tableau par valeur n’empêche pas les modifications des éléments du tableau.

class ArrayExample
{
    static void DisplayArray(string[] arr) => Console.WriteLine(string.Join(" ", arr));

    // Change the array by reversing its elements.
    static void ChangeArray(string[] arr) => Array.Reverse(arr);

    static void ChangeArrayElements(string[] arr)
    {
        // Change the value of the first three array elements.
        arr[0] = "Mon";
        arr[1] = "Wed";
        arr[2] = "Fri";
    }

    static void Main()
    {
        // Declare and initialize an array.
        string[] weekDays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
        // Display the array elements.
        DisplayArray(weekDays);
        Console.WriteLine();

        // Reverse the array.
        ChangeArray(weekDays);
        // Display the array again to verify that it stays reversed.
        Console.WriteLine("Array weekDays after the call to ChangeArray:");
        DisplayArray(weekDays);
        Console.WriteLine();

        // Assign new values to individual array elements.
        ChangeArrayElements(weekDays);
        // Display the array again to verify that it has changed.
        Console.WriteLine("Array weekDays after the call to ChangeArrayElements:");
        DisplayArray(weekDays);
    }
}
// The example displays the following output:
//         Sun Mon Tue Wed Thu Fri Sat
//
//        Array weekDays after the call to ChangeArray:
//        Sat Fri Thu Wed Tue Mon Sun
//
//        Array weekDays after the call to ChangeArrayElements:
//        Mon Wed Fri Wed Tue Mon Sun

Tableaux multidimensionnels

Les tableaux peuvent avoir plusieurs dimensions. Par exemple, les déclarations suivantes créent quatre tableaux : deux ont deux dimensions, deux ont trois dimensions. Les deux premières déclarations déclarent la longueur de chaque dimension, mais n’initialisent pas les valeurs du tableau. Les deux deuxièmes déclarations utilisent un initialiseur pour définir les valeurs de chaque élément dans le tableau multidimensionnel.

int[,] array2DDeclaration = new int[4, 2];

int[,,] array3DDeclaration = new int[4, 2, 3];

// Two-dimensional array.
int[,] array2DInitialization =  { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
// Three-dimensional array.
int[,,] array3D = new int[,,] { { { 1, 2, 3 }, { 4,   5,  6 } },
                                { { 7, 8, 9 }, { 10, 11, 12 } } };

// Accessing array elements.
System.Console.WriteLine(array2DInitialization[0, 0]);
System.Console.WriteLine(array2DInitialization[0, 1]);
System.Console.WriteLine(array2DInitialization[1, 0]);
System.Console.WriteLine(array2DInitialization[1, 1]);

System.Console.WriteLine(array2DInitialization[3, 0]);
System.Console.WriteLine(array2DInitialization[3, 1]);
// Output:
// 1
// 2
// 3
// 4
// 7
// 8

System.Console.WriteLine(array3D[1, 0, 1]);
System.Console.WriteLine(array3D[1, 1, 2]);
// Output:
// 8
// 12

// Getting the total count of elements or the length of a given dimension.
var allLength = array3D.Length;
var total = 1;
for (int i = 0; i < array3D.Rank; i++)
{
    total *= array3D.GetLength(i);
}
System.Console.WriteLine($"{allLength} equals {total}");
// Output:
// 12 equals 12

Pour les tableaux multidimensionnels, les éléments sont traités de sorte que les index de la dimension la plus à droite sont incrémentés en premier, puis la dimension immédiatement à gauche, et ainsi de suite jusqu’à l’index le plus à gauche. L’exemple suivant énumère à la fois un tableau 2D et un tableau 3D :

int[,] numbers2D = { { 9, 99 }, { 3, 33 }, { 5, 55 } };

foreach (int i in numbers2D)
{
    System.Console.Write($"{i} ");
}
// Output: 9 99 3 33 5 55

int[,,] array3D = new int[,,] { { { 1, 2, 3 }, { 4,   5,  6 } },
                        { { 7, 8, 9 }, { 10, 11, 12 } } };
foreach (int i in array3D)
{
    System.Console.Write($"{i} ");
}
// Output: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12

Dans un tableau 2D, vous pouvez considérer l’index de gauche comme la ligne et l’index de droite comme la colonne.

Cependant, dans le cas de tableaux multidimensionnels, l’utilisation d’une boucle for imbriquée vous permet de mieux contrôler l’ordre dans lequel les éléments du tableau sont traités :

int[,,] array3D = new int[,,] { { { 1, 2, 3 }, { 4,   5,  6 } },
                        { { 7, 8, 9 }, { 10, 11, 12 } } };

for (int i = 0; i < array3D.GetLength(0); i++)
{
    for (int j = 0; j < array3D.GetLength(1); j++)
    {
        for (int k = 0; k < array3D.GetLength(2); k++)
        {
            System.Console.Write($"{array3D[i, j, k]} ");
        }
        System.Console.WriteLine();
    }
    System.Console.WriteLine();
}
// Output (including blank lines): 
// 1 2 3
// 4 5 6
// 
// 7 8 9
// 10 11 12
//

Passer des tableaux multidimensionnels en tant qu’arguments

Vous pouvez passer un tableau multidimensionnel initialisé à une méthode de la même manière que vous passez un tableau unidimensionnel. Le code suivant illustre une déclaration partielle d’une méthode Print qui accepte un tableau à deux dimensions en tant qu’argument. Vous pouvez initialiser et passer un nouveau tableau en une seule étape, comme dans l’exemple suivant. Dans l’exemple suivant, un tableau à deux dimensions d’entiers est initialisé et passé à la méthode Print2DArray. La méthode affiche les éléments du tableau.

static void Print2DArray(int[,] arr)
{
    // Display the array elements.
    for (int i = 0; i < arr.GetLength(0); i++)
    {
        for (int j = 0; j < arr.GetLength(1); j++)
        {
            System.Console.WriteLine("Element({0},{1})={2}", i, j, arr[i, j]);
        }
    }
}
static void ExampleUsage()
{
    // Pass the array as an argument.
    Print2DArray(new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } });
}
/* Output:
    Element(0,0)=1
    Element(0,1)=2
    Element(1,0)=3
    Element(1,1)=4
    Element(2,0)=5
    Element(2,1)=6
    Element(3,0)=7
    Element(3,1)=8
*/

Tableaux en escalier

Un tableau en escalier est un tableau dont les éléments sont des tableaux, éventuellement de différentes tailles. Un tableau en escalier est parfois appelé « tableau de tableaux ». Ses éléments sont des types de référence et sont initialisés sur null. Les exemples suivants montrent comment déclarer, initialiser et accéder aux tableaux en escalier. Le premier exemple, jaggedArray, est déclaré dans une instruction. Chaque tableau contenu est créé dans les instructions suivantes. Le deuxième exemple, jaggedArray2, est déclaré et initialisé dans une instruction. Il est possible de combiner des tableaux en escalier et des tableaux multidimensionnels. Le dernier exemple, jaggedArray3, déclare et initialise un tableau en escalier unidimensionnel composé de trois éléments de tableau à deux dimensions de tailles différentes.

int[][] jaggedArray = new int[3][];

jaggedArray[0] = [1, 3, 5, 7, 9];
jaggedArray[1] = [0, 2, 4, 6];
jaggedArray[2] = [11, 22];

int[][] jaggedArray2 = 
[
    [1, 3, 5, 7, 9],
    [0, 2, 4, 6],
    [11, 22]
];

// Assign 77 to the second element ([1]) of the first array ([0]):
jaggedArray2[0][1] = 77;

// Assign 88 to the second element ([1]) of the third array ([2]):
jaggedArray2[2][1] = 88;

int[][,] jaggedArray3 =
[
    new int[,] { {1,3}, {5,7} },
    new int[,] { {0,2}, {4,6}, {8,10} },
    new int[,] { {11,22}, {99,88}, {0,9} }
];

Console.Write("{0}", jaggedArray3[0][1, 0]);
Console.WriteLine(jaggedArray3.Length);

Les éléments d’un tableau en escalier doivent être initialisés avant de pouvoir les utiliser. Chacun des éléments est lui-même un tableau. Il est également possible d’utiliser des initialiseurs pour remplir les éléments de tableau avec des valeurs. Lorsque vous utilisez des initialiseurs, vous n’avez pas besoin de la taille du tableau.

Cet exemple génère un tableau dont les éléments sont eux-mêmes des tableaux. Chacun des éléments de tableau ont une taille différente.

// Declare the array of two elements.
int[][] arr = new int[2][];

// Initialize the elements.
arr[0] = [1, 3, 5, 7, 9];
arr[1] = [2, 4, 6, 8];

// Display the array elements.
for (int i = 0; i < arr.Length; i++)
{
    System.Console.Write("Element({0}): ", i);

    for (int j = 0; j < arr[i].Length; j++)
    {
        System.Console.Write("{0}{1}", arr[i][j], j == (arr[i].Length - 1) ? "" : " ");
    }
    System.Console.WriteLine();
}
/* Output:
    Element(0): 1 3 5 7 9
    Element(1): 2 4 6 8
*/

Tableaux implicitement typés

Vous pouvez créer un tableau implicitement typé dans lequel le type de l’instance de tableau est déduit à partir des éléments spécifiés dans l’initialiseur de tableau. Les règles applicables à une variable implicitement typée s’appliquent aussi aux tableaux implicitement typés. Pour plus d’informations, consultez Variables locales implicitement typées.

Les exemples suivants montrent comment créer un tableau implicitement typé :

int[] a = new[] { 1, 10, 100, 1000 }; // int[]

// Accessing array
Console.WriteLine("First element: " + a[0]);
Console.WriteLine("Second element: " + a[1]);
Console.WriteLine("Third element: " + a[2]);
Console.WriteLine("Fourth element: " + a[3]);
/* Outputs
First element: 1
Second element: 10
Third element: 100
Fourth element: 1000
*/

var b = new[] { "hello", null, "world" }; // string[]

// Accessing elements of an array using 'string.Join' method
Console.WriteLine(string.Join(" ", b));
/* Output
hello  world
*/

// single-dimension jagged array
int[][] c =
[
    [1,2,3,4],
    [5,6,7,8]
];
// Looping through the outer array
for (int k = 0; k < c.Length; k++)
{
    // Looping through each inner array
    for (int j = 0; j < c[k].Length; j++)
    {
        // Accessing each element and printing it to the console
        Console.WriteLine($"Element at c[{k}][{j}] is: {c[k][j]}");
    }
}
/* Outputs
Element at c[0][0] is: 1
Element at c[0][1] is: 2
Element at c[0][2] is: 3
Element at c[0][3] is: 4
Element at c[1][0] is: 5
Element at c[1][1] is: 6
Element at c[1][2] is: 7
Element at c[1][3] is: 8
*/

// jagged array of strings
string[][] d =
[
    ["Luca", "Mads", "Luke", "Dinesh"],
    ["Karen", "Suma", "Frances"]
];

// Looping through the outer array
int i = 0;
foreach (var subArray in d)
{
    // Looping through each inner array
    int j = 0;
    foreach (var element in subArray)
    {
        // Accessing each element and printing it to the console
        Console.WriteLine($"Element at d[{i}][{j}] is: {element}");
        j++;
    }
    i++;
}
/* Outputs
Element at d[0][0] is: Luca
Element at d[0][1] is: Mads
Element at d[0][2] is: Luke
Element at d[0][3] is: Dinesh
Element at d[1][0] is: Karen
Element at d[1][1] is: Suma
Element at d[1][2] is: Frances
*/

Dans l’exemple précédent, vous pouvez constater que dans le cas des tableaux implicitement typés, aucun crochet n’est utilisé à gauche de l’instruction d’initialisation. De plus, les tableaux en escalier sont initialisés à l’aide de new [] à l’instar des tableaux unidimensionnels.

Quand vous créez un type anonyme qui contient un tableau, le tableau doit être implicitement typé dans l’initialiseur d’objet du type. Dans l’exemple suivant, contacts est un tableau implicitement typé de types anonymes, dont chacun contient un tableau nommé PhoneNumbers. Le mot clé var n’est pas utilisé dans les initialiseurs d’objets.

var contacts = new[]
{
    new
    {
        Name = "Eugene Zabokritski",
        PhoneNumbers = new[] { "206-555-0108", "425-555-0001" }
    },
    new
    {
        Name = "Hanying Feng",
        PhoneNumbers = new[] { "650-555-0199" }
    }
};