C# Language
Tablice
Szukaj…
Składnia
Deklarowanie tablicy:
<typ> [] <nazwa>;
Deklarowanie tablicy dwuwymiarowej:
<typ> [,] <nazwa> = nowy <typ> [<wartość>, <wartość>];
Deklarowanie poszarpanej tablicy:
<typ> [] <nazwa> = nowy <typ> [<wartość>];
Deklarowanie podtablicy dla tablicy Jagged Array:
<nazwa> [<wartość>] = nowy <typ> [<wartość>];
Inicjowanie tablicy bez wartości:
<nazwa> = nowy <typ> [<długość>];
Inicjowanie tablicy z wartościami:
<nazwa> = nowy <typ> [] {<wartość>, <wartość>, <wartość>, ...};
Inicjowanie tablicy dwuwymiarowej za pomocą wartości:
<nazwa> = nowy <typ> [,] {{<wartość>, <wartość>}, {<wartość>, <wartość>}, ...};
Dostęp do elementu o indeksie i:
<nazwa> [i]
Uzyskiwanie długości tablicy:
<nazwa> .Długość
Uwagi
W języku C # tablica jest typem odwołania, co oznacza, że można ją zerować .
Tablica ma stałą długość, co oznacza, że nie .Add()
do niej .Add()
ani .Remove()
. Aby ich użyć, potrzebujesz dynamicznej tablicy - List
lub ArrayList
.
Tablica kowariancji
string[] strings = new[] {"foo", "bar"};
object[] objects = strings; // implicit conversion from string[] to object[]
Ta konwersja nie jest bezpieczna dla typu. Poniższy kod zgłosi wyjątek czasu wykonywania:
string[] strings = new[] {"Foo"};
object[] objects = strings;
objects[0] = new object(); // runtime exception, object is not string
string str = strings[0]; // would have been bad if above assignment had succeeded
Pobieranie i ustawianie wartości tablic
int[] arr = new int[] { 0, 10, 20, 30};
// Get
Console.WriteLine(arr[2]); // 20
// Set
arr[2] = 100;
// Get the updated value
Console.WriteLine(arr[2]); // 100
Deklarowanie tablicy
Tablicę można zadeklarować i wypełnić wartością domyślną za pomocą składni inicjalizacji nawiasu kwadratowego ( []
). Na przykład utworzenie tablicy 10 liczb całkowitych:
int[] arr = new int[10];
Indeksy w języku C # są zerowane. Wskaźniki powyższej tablicy będą wynosić 0–9. Na przykład:
int[] arr = new int[3] {7,9,4};
Console.WriteLine(arr[0]); //outputs 7
Console.WriteLine(arr[1]); //outputs 9
Co oznacza, że system zaczyna zliczać indeks elementów od 0. Ponadto dostęp do elementów tablic odbywa się w stałym czasie . Oznacza to, że dostęp do pierwszego elementu tablicy ma taki sam koszt (w czasie) dostępu do drugiego elementu, trzeciego elementu i tak dalej.
Możesz także zadeklarować odsyłacz do tablicy bez tworzenia instancji.
int[] arr = null; // OK, declares a null reference to an array.
int first = arr[0]; // Throws System.NullReferenceException because there is no actual array.
Tablicę można również utworzyć i zainicjować za pomocą niestandardowych wartości przy użyciu składni inicjalizacji kolekcji:
int[] arr = new int[] { 24, 2, 13, 47, 45 };
new int[]
część new int[]
może zostać pominięta przy deklarowaniu zmiennej tablicowej. To nie jest samodzielne wyrażenie , więc użycie go jako części innego wywołania nie działa (w tym celu użyj wersji z new
):
int[] arr = { 24, 2, 13, 47, 45 }; // OK
int[] arr1;
arr1 = { 24, 2, 13, 47, 45 }; // Won't compile
Tablice niejawnie wpisane
Alternatywnie, w połączeniu ze słowem kluczowym var
, można pominąć konkretny typ, aby wywnioskować typ tablicy:
// same as int[]
var arr = new [] { 1, 2, 3 };
// same as string[]
var arr = new [] { "one", "two", "three" };
// same as double[]
var arr = new [] { 1.0, 2.0, 3.0 };
Iteruj po tablicy
int[] arr = new int[] {1, 6, 3, 3, 9};
for (int i = 0; i < arr.Length; i++)
{
Console.WriteLine(arr[i]);
}
przy użyciu foreach:
foreach (int element in arr)
{
Console.WriteLine(element);
}
korzystanie z niebezpiecznego dostępu ze wskaźnikami https://msdn.microsoft.com/en-ca/library/y31yhkeb.aspx
unsafe
{
int length = arr.Length;
fixed (int* p = arr)
{
int* pInt = p;
while (length-- > 0)
{
Console.WriteLine(*pInt);
pInt++;// move pointer to next element
}
}
}
Wynik:
1
6
3)
3)
9
Tablice wielowymiarowe
Tablice mogą mieć więcej niż jeden wymiar. Poniższy przykład tworzy dwuwymiarową tablicę dziesięciu wierszy i dziesięciu kolumn:
int[,] arr = new int[10, 10];
Tablica trzech wymiarów:
int[,,] arr = new int[10, 10, 10];
Możesz także zainicjować tablicę po deklaracji:
int[,] arr = new int[4, 2] { {1, 1}, {2, 2}, {3, 3}, {4, 4} };
// Access a member of the multi-dimensional array:
Console.Out.WriteLine(arr[3, 1]); // 4
Postrzępione tablice
Tablice poszarpane to tablice, które zamiast typów pierwotnych zawierają tablice (lub inne kolekcje). To jest jak tablica tablic - każdy element tablicy zawiera inną tablicę.
Są podobne do tablic wielowymiarowych, ale mają niewielką różnicę - ponieważ tablice wielowymiarowe są ograniczone do stałej liczby wierszy i kolumn, z tablicami postrzępionymi, każdy wiersz może mieć inną liczbę kolumn.
Deklaracja poszarpanej tablicy
Na przykład deklarowanie poszarpanej tablicy z 8 kolumnami:
int[][] a = new int[8][];
Drugi []
jest inicjowany bez numeru. Aby zainicjować tablice podrzędne, musisz to zrobić osobno:
for (int i = 0; i < a.length; i++)
{
a[i] = new int[10];
}
Pobieranie / ustawianie wartości
Teraz uzyskanie jednego z podrzędnych jest łatwe. Załóżmy wydrukować wszystkie numery 3rd kolumnie : a
for (int i = 0; i < a[2].length; i++)
{
Console.WriteLine(a[2][i]);
}
Uzyskiwanie określonej wartości:
a[<row_number>][<column_number>]
Ustawianie określonej wartości:
a[<row_number>][<column_number>] = <value>
Pamiętaj : zawsze zaleca się stosowanie tablic postrzępionych (tablic tablic) zamiast tablic wielowymiarowych (matryc). Jest szybszy i bezpieczniejszy w użyciu.
Uwaga na kolejność nawiasów
Rozważ trójwymiarową tablicę pięciowymiarowych tablic jednowymiarowych tablic int
. Jest to napisane w języku C # jako:
int[,,][,,,,][] arr = new int[8, 10, 12][,,,,][];
W systemie typu CLR konwencja porządkowania nawiasów jest odwrócona, więc w powyższej instancji arr
mamy:
arr.GetType().ToString() == "System.Int32[][,,,,][,,]"
I podobnie:
typeof(int[,,][,,,,][]).ToString() == "System.Int32[][,,,,][,,]"
Sprawdzanie, czy jedna tablica zawiera inną tablicę
public static class ArrayHelpers
{
public static bool Contains<T>(this T[] array, T[] candidate)
{
if (IsEmptyLocate(array, candidate))
return false;
if (candidate.Length > array.Length)
return false;
for (int a = 0; a <= array.Length - candidate.Length; a++)
{
if (array[a].Equals(candidate[0]))
{
int i = 0;
for (; i < candidate.Length; i++)
{
if (false == array[a + i].Equals(candidate[i]))
break;
}
if (i == candidate.Length)
return true;
}
}
return false;
}
static bool IsEmptyLocate<T>(T[] array, T[] candidate)
{
return array == null
|| candidate == null
|| array.Length == 0
|| candidate.Length == 0
|| candidate.Length > array.Length;
}
}
/// Próbka
byte[] EndOfStream = Encoding.ASCII.GetBytes("---3141592---");
byte[] FakeReceivedFromStream = Encoding.ASCII.GetBytes("Hello, world!!!---3141592---");
if (FakeReceivedFromStream.Contains(EndOfStream))
{
Console.WriteLine("Message received");
}
Inicjowanie tablicy wypełnionej powtarzającą się wartością inną niż domyślna
Jak wiemy, możemy zadeklarować tablicę z wartościami domyślnymi:
int[] arr = new int[10];
Spowoduje to utworzenie tablicy 10 liczb całkowitych z każdym elementem tablicy o wartości 0
(domyślna wartość typu int
).
Aby utworzyć tablicę zainicjowaną wartością inną niż domyślna, możemy użyć Enumerable.Repeat
z przestrzeni nazw System.Linq
:
Aby utworzyć tablicę
bool
o rozmiarze 10 wypełnioną „true”bool[] booleanArray = Enumerable.Repeat(true, 10).ToArray();
Aby utworzyć tablicę
int
o rozmiarze 5 wypełnioną „100”int[] intArray = Enumerable.Repeat(100, 5).ToArray();
Aby utworzyć tablicę
string
o rozmiarze 5 wypełnioną „C #”string[] strArray = Enumerable.Repeat("C#", 5).ToArray();
Kopiowanie tablic
Kopiowanie częściowej tablicy za pomocą statycznej metody Array.Copy()
, zaczynając od indeksu 0 zarówno w źródle, jak i miejscu docelowym:
var sourceArray = new int[] { 11, 12, 3, 5, 2, 9, 28, 17 };
var destinationArray= new int[3];
Array.Copy(sourceArray, destinationArray, 3);
// destinationArray will have 11,12 and 3
Kopiowanie całej tablicy za pomocą metody instancji CopyTo()
, zaczynając od indeksu 0 źródła i określonego indeksu w miejscu docelowym:
var sourceArray = new int[] { 11, 12, 7 };
var destinationArray = new int[6];
sourceArray.CopyTo(destinationArray, 2);
// destinationArray will have 0, 0, 11, 12, 7 and 0
Clone
służy do utworzenia kopii obiektu tablicy.
var sourceArray = new int[] { 11, 12, 7 };
var destinationArray = (int)sourceArray.Clone();
//destinationArray will be created and will have 11,12,17.
Zarówno CopyTo
jak i Clone
wykonują płytkie kopiowanie, co oznacza, że zawartość zawiera odwołania do tego samego obiektu, co elementy w oryginalnej tablicy.
Tworzenie tablicy kolejnych numerów
LINQ zapewnia metodę, która ułatwia tworzenie kolekcji wypełnionej kolejnymi numerami. Na przykład możesz zadeklarować tablicę zawierającą liczby całkowite od 1 do 100.
Metoda Enumerable.Range
pozwala nam tworzyć sekwencje liczb całkowitych z określonej pozycji początkowej i szeregu elementów.
Metoda przyjmuje dwa argumenty: wartość początkową i liczbę elementów do wygenerowania.
Enumerable.Range(int start, int count)
Pamiętaj, że count
nie może być ujemna.
Stosowanie:
int[] sequence = Enumerable.Range(1, 100).ToArray();
Spowoduje to wygenerowanie tablicy zawierającej liczby od 1 do 100 ( [1, 2, 3, ..., 98, 99, 100]
).
Ponieważ metoda Range
zwraca IEnumerable<int>
, możemy na niej użyć innych metod LINQ:
int[] squares = Enumerable.Range(2, 10).Select(x => x * x).ToArray();
Wygeneruje to tablicę zawierającą 10 liczb całkowitych zaczynających się od 4
: [4, 9, 16, ..., 100, 121]
.
Porównywanie tablic dla równości
LINQ zapewnia wbudowaną funkcję sprawdzania równości dwóch IEnumerable
s, i ta funkcja może być używana na tablicach.
Funkcja SequenceEqual
zwróci true
jeśli tablice mają tę samą długość, a wartości w odpowiednich indeksach są równe, a false
przeciwnym razie.
int[] arr1 = { 3, 5, 7 };
int[] arr2 = { 3, 5, 7 };
bool result = arr1.SequenceEqual(arr2);
Console.WriteLine("Arrays equal? {0}", result);
Spowoduje to wydrukowanie:
Arrays equal? True
Tablice jako instancje IEnumerable <>
Wszystkie tablice implementują nie-ogólny interfejs IList
(a zatem nie-ogólny ICollection
i IEnumerable
interfejsy podstawowe).
Co ważniejsze, jednowymiarowe tablice implementują ogólne interfejsy IList<>
i IReadOnlyList<>
(i ich podstawowe interfejsy) dla typu danych, które zawierają. Oznacza to, że można je traktować jako ogólne typy wyliczalne i przekazywać do różnych metod bez konieczności uprzedniej konwersji ich do postaci innej niż tablica.
int[] arr1 = { 3, 5, 7 };
IEnumerable<int> enumerableIntegers = arr1; //Allowed because arrays implement IEnumerable<T>
List<int> listOfIntegers = new List<int>();
listOfIntegers.AddRange(arr1); //You can pass in a reference to an array to populate a List.
Po uruchomieniu tego kodu lista listOfIntegers
będzie zawierać List<int>
zawierający wartości 3, 5 i 7.
Obsługa IEnumerable<>
oznacza, że tablice można przeszukiwać za pomocą LINQ, na przykład arr1.Select(i => 10 * i)
.