Udostępnij za pośrednictwem


Tablice

Można przechowywać wiele zmiennych tego samego typu w strukturze danych tablicy. Zadeklaruj tablicę, określając typ jej elementów. Jeśli chcesz, aby tablica przechowywała elementy dowolnego typu, możesz określić object jej typ. W ujednoliconym systemie języka C#, wszystkie typy, wstępnie zdefiniowane i zdefiniowane przez użytkownika, typy referencyjne i typy wartości dziedziczą bezpośrednio lub pośrednio z Objectklasy .

type[] arrayName;

Tablica jest typem odwołania, więc tablica może być odwołaniem dopuszczanym do wartości null typem. Typy elementów mogą być typami referencyjnymi, więc można zadeklarować tablicę do przechowywania typów referencyjnych, które mogą przyjmować wartość null. Poniższe przykładowe deklaracje pokazują inną składnię używaną do deklarowania wartości null tablicy lub elementów:

type?[] arrayName; // non nullable array of nullable element types.
type[]? arrayName; // nullable array of non-nullable element types.
type?[]? arrayName; // nullable array of nullable element types.

Niezainicjowane elementy w tablicy są ustawione na wartość domyślną dla tego typu:

int[] numbers = new int[10]; // All values are 0
string[] messages = new string[10]; // All values are null.

Ważne

W poprzednim przykładzie, mimo że typ to string[], czyli tablica niemających wartości null ciągów, domyślną wartością dla każdego elementu jest null. Najlepszym sposobem zainicjowania tablicy na wartości inne niż null jest użycie wyrażeń kolekcji .

Tablica ma następujące właściwości:

  • Tablica może być jednowymiarowa, wielowymiarowa lub postrzępiona.
  • Liczba wymiarów jest ustawiana po zadeklarowaniu zmiennej tablicowej. Długość każdego wymiaru jest ustalana podczas tworzenia wystąpienia tablicy. Tych wartości nie można zmienić w okresie istnienia wystąpienia.
  • Tablica postrzępiona jest tablicą tablic, a każda tablica składowa ma wartość nulldomyślną .
  • Tablice są indeksowane zero: tablica z elementami n jest indeksowana z 0 do n-1.
  • Elementy tablicy mogą być dowolnym typem, w tym typem tablicy.
  • Typy tablic są typami referencyjnymi pochodzącymi z abstrakcyjnego typu Arraypodstawowego . Wszystkie tablice implementują i IListIEnumerable. Instrukcję foreach można użyć do iterowania tablicy. Tablice jednowymiarowe implementują IList<T> również i IEnumerable<T>.

Elementy tablicy można zainicjować do znanych wartości podczas tworzenia tablicy. Począwszy od języka C# 12, wszystkie typy kolekcji można zainicjować przy użyciu wyrażenia Kolekcja. Elementy, które nie są inicjowane, są ustawione na wartość domyślną. Wartość domyślna to wzorzec 0-bitowy. Wszystkie typy odwołań (w tym typy niezwiązane z wartościami null) mają wartości null. Wszystkie typy wartości mają wzorce 0-bitowe. Oznacza to, Nullable<T>.HasValue że właściwość jest false i Nullable<T>.Value właściwość jest niezdefiniowana. We implementacji Value platformy .NET właściwość zgłasza wyjątek.

Poniższy przykład tworzy tablice jednowymiarowe, wielowymiarowe i postrzępione:

// 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];

Ważne

Wiele przykładów w tym artykule używa wyrażeń kolekcji (które używają nawiasów kwadratowych) do inicjowania tablic. Wyrażenia kolekcji zostały po raz pierwszy wprowadzone w języku C# 12, które zostały dostarczone z platformą .NET 8. Jeśli nie możesz jeszcze uaktualnić do wersji C# 12, użyj polecenia { i } , aby zainicjować tablice.

// Collection expressions:
int[] array = [1, 2, 3, 4, 5, 6];
// Alternative syntax:
int[] array2 = {1, 2, 3, 4, 5, 6};

Tablice jednowymiarowe

Jednowymiarowa tablica jest sekwencją podobnych elementów. Dostęp do elementu można uzyskać za pośrednictwem jego indeksu. Indeks jest pozycją porządkową w sekwencji. Pierwszym elementem tablicy jest indeks 0. Tablica jednowymiarowa jest tworzona przy użyciu nowego operatora określającego typ elementu tablicy i liczbę elementów. Poniższy przykład deklaruje i inicjuje tablice jednowymiarowe:

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
*/

Pierwsza deklaracja deklaruje niezainicjowaną tablicę pięciu liczb całkowitych z array[0] do array[4]. Elementy tablicy są inicjowane do wartości domyślnej typu 0 elementu dla liczb całkowitych. Druga deklaracja deklaruje tablicę ciągów i inicjuje wszystkie siedem wartości tej tablicy. Seria instrukcji Console.WriteLine wyświetla wszystkie elementy weekDay tablicy. W przypadku tablic jednowymiarowych foreach instrukcja przetwarza elementy w kolejności rosnącej indeksu, począwszy od indeksu 0 i kończąc na indeksie Length - 1.

Przekazywanie tablic jednowymiarowych jako argumentów

Do metody można przekazać zainicjowaną jednowymiarową tablicę. W poniższym przykładzie tablica ciągów jest inicjowana i przekazywana jako argument do DisplayArray metody ciągów. Metoda wyświetla elementy tablicy. ChangeArray Następnie metoda odwraca elementy tablicy, a następnie ChangeArrayElements metoda modyfikuje pierwsze trzy elementy tablicy. Po dokonaniu każdej metody metoda pokazuje, DisplayArray że przekazywanie tablicy według wartości nie uniemożliwia zmian w elementach tablicy.

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

Tablice wielowymiarowe

Tablice mogą mieć więcej niż jeden wymiar. Na przykład następujące deklaracje tworzą cztery tablice. Dwie tablice mają dwa wymiary. Dwie tablice mają trzy wymiary. Pierwsze dwie deklaracje deklarują długość każdego wymiaru, ale nie inicjują wartości tablicy. Drugie dwie deklaracje używają inicjatora do ustawiania wartości każdego elementu w tablicy wielowymiarowej.

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

W przypadku tablic wielowymiarowych elementy są przechodzine w taki sposób, że indeksy wymiaru po prawej stronie są najpierw zwiększane, a następnie następny wymiar po lewej stronie, a tak dalej, do indeksu najbardziej po lewej stronie. Poniższy przykład wylicza zarówno tablicę 2D, jak i tablicę 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

W tablicy 2D można traktować indeks po lewej stronie jako wiersz i prawy indeks jako kolumnę.

Jednak w przypadku tablic wielowymiarowych użycie zagnieżdżonej pętli zapewnia większą kontrolę nad kolejnością przetwarzania elementów tablicy:

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
//

Przekazywanie tablic wielowymiarowych jako argumentów

Zainicjowana tablica wielowymiarowa jest przekazywana do metody w taki sam sposób, jak w przypadku przekazywania tablicy jednowymiarowej. Poniższy kod przedstawia częściową deklarację metody print, która akceptuje tablicę dwuwymiarową jako argument. Można zainicjować i przekazać nową tablicę w jednym kroku, jak pokazano w poniższym przykładzie. W poniższym przykładzie jest inicjowana dwuwymiarowa tablica liczb całkowitych i przekazywana Print2DArray do metody . Metoda wyświetla elementy tablicy.

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
*/

Tablice postrzępione

Tablica postrzępiona to tablica, której elementy są tablicami, prawdopodobnie o różnych rozmiarach. Tablica postrzępiona jest czasami nazywana "tablicą tablic". Jego elementy są typami referencyjnymi i są inicjowane na null. W poniższych przykładach pokazano, jak zadeklarować, zainicjować i uzyskać dostęp do tablic postrzępionych. Pierwszy przykład jaggedArray, jest zadeklarowany w jednej instrukcji. Każda zawarta tablica jest tworzona w kolejnych instrukcjach. Drugi przykład jaggedArray2 jest zadeklarowany i zainicjowany w jednej instrukcji. Można mieszać tablice postrzępione i wielowymiarowe. Ostatnim przykładem jest jaggedArray3deklaracja i inicjowanie jednowymiarowej tablicy postrzępionej, która zawiera trzy dwuwymiarowe elementy tablicy o różnych rozmiarach.

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);

Przed ich użyciem należy zainicjować elementy tablicy postrzępionej. Każda z tych elementów jest tablicą. Za pomocą inicjatorów można również wypełnić elementy tablicy wartościami. W przypadku używania inicjatorów nie potrzebujesz rozmiaru tablicy.

W tym przykładzie utworzono tablicę, której elementy są tablicami. Każdy z elementów tablicy ma inny rozmiar.

// 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
*/

Niejawnie wpisane tablice

Można utworzyć niejawnie typizowanej tablicy, w której typ wystąpienia tablicy jest wnioskowany z elementów określonych w inicjatorze tablicy. Reguły dla dowolnej niejawnie typizowanej zmiennej mają również zastosowanie do niejawnie wpisanych tablic. Aby uzyskać więcej informacji, zobacz Niejawnie wpisane zmienne lokalne.

W poniższych przykładach pokazano, jak utworzyć niejawnie typizowane tablicy:

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
*/

W poprzednim przykładzie zwróć uwagę, że w przypadku niejawnie wpisanych tablic nie są używane nawiasy kwadratowe po lewej stronie instrukcji inicjowania. Ponadto tablice postrzępione są inicjowane przy użyciu new [] tak samo jak tablice jednowymiarowe.

Podczas tworzenia typu anonimowego, który zawiera tablicę, tablica musi być niejawnie wpisywana w inicjatorze obiektu typu. W poniższym przykładzie contacts jest niejawnie typizowane tablicy typów anonimowych, z których każda zawiera tablicę o nazwie PhoneNumbers. Słowo var kluczowe nie jest używane wewnątrz inicjatorów obiektów.

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