Un array contiene un numero fisso di elementi dello stesso tipo, memorizzati uno accanto all'altro in memoria. Scegli la lunghezza quando lo crei, leggi e scrivi gli elementi tramite un indice che parte da zero, e dopo di allora la lunghezza non cambia più.
Dichiarare e inizializzare un array
Il tipo di un array è il tipo degli elementi seguito da []. Ci sono diversi modi per crearne uno:
Output:
90, 0, 0, 72
Ben
2 prices, 3 days
new int[4] riempie ogni elemento con il valore predefinito del tipo: 0 per i numeri, false per bool, null per le stringhe e gli altri tipi riferimento. La forma breve { "Ana", "Ben" } funziona solo in una dichiarazione; quando assegni a una variabile esistente ti serve names = new[] { "Dev", "Eli" };.
Length, indici e ultimo elemento
Gli indici vanno da 0 a Length - 1. Length è una proprietà, quindi non ha parentesi (a differenza del metodo Count() di LINQ).
Output:
Count: 5
First: 18
Last: 16
Caught IndexOutOfRangeException
Leggere o scrivere fuori dai limiti lancia IndexOutOfRangeException a runtime; il compilatore non se ne accorge. La causa tipica è una condizione di ciclo scritta come i <= arr.Length invece di i < arr.Length.
C# 8 e versioni successive aggiungono la sintassi degli indici dalla fine e degli intervalli, più breve per l'ultimo elemento e per le porzioni:
int last = temps[^1]; // 16
int[] middle = temps[1..4]; // { 21, 25, 19 }, a new array
Scorrere un array con un ciclo
Un ciclo for ti dà l'indice; foreach ti dà ogni elemento ed è la scelta più chiara quando devi solo leggere.
Output:
4.95 | 13.20 | 3.58
Total: 21.73
La variabile del foreach è di sola lettura: p = 0; dentro il ciclo è un errore di compilazione. Per modificare gli elementi, usa un ciclo con indice.
Ordinare, invertire e cercare
La classe statica Array contiene i metodi di supporto. Array.Sort ordina sul posto e non restituisce nulla, quindi l'ordine originale va perso.
Output:
Ascending: 60, 72, 79, 88, 95
Descending: 95, 88, 79, 72, 60
Index of 60: 4
Index of 99: -1
Any above 90: True
First below 75: 72
Ana, ben, chloe
fig, kiwi, banana
Array.IndexOf restituisce -1 quando il valore non c'è. Array.Find restituisce il valore predefinito del tipo (0 qui) quando nulla corrisponde, cosa ambigua per i numeri; usa Array.FindIndex quando conta. Un ordinamento decrescente in una sola chiamata è Array.Sort(scores, (a, b) => b.CompareTo(a)).
Se ti serve il risultato ordinato senza toccare l'originale, LINQ restituisce un nuovo array: var sorted = scores.OrderBy(s => s).ToArray();. Vedi LINQ.
Ridimensionare: un array non può crescere
La lunghezza è fissa. Array.Resize crea un nuovo array della dimensione richiesta, copia gli elementi e aggiorna la variabile che passi con ref.
Output:
4
2
True
False
Ogni ridimensionamento copia tutti gli elementi. Far crescere un array di un elemento alla volta in un ciclo è lento, ed è esattamente ciò che List<T> fa per te in modo più efficiente, raddoppiando il suo array interno.
Gli array sono tipi riferimento: la copia
Assegnare un array a un'altra variabile copia il riferimento, non gli elementi. A quel punto entrambi i nomi puntano allo stesso array.
Output:
100
2
0, 100, 2, 3, 0
Lo stesso vale quando passi un array a un metodo: il metodo può modificare gli elementi del chiamante. Clone, Array.Copy, CopyTo e ToArray() di LINQ fanno tutti una copia superficiale. Per un array di oggetti, il nuovo array contiene riferimenti agli stessi oggetti, quindi modificare copy[0].Name cambia comunque ciò che vede original[0].
Confrontare array con == confronta i riferimenti. Per confrontare i contenuti usa a.SequenceEqual(b) da System.Linq.
Array 2D (multidimensionali)
Una griglia rettangolare si dichiara con una virgola dentro le parentesi quadre. La indicizzi con [row, col].
Output:
Rows: 2
Cols: 3
Length: 6, Rank: 2
. X .
. . X
Length su un array 2D è il numero totale di elementi (6 per una griglia 2 per 3), ed è per questo che i cicli annidati usano GetLength(0) e GetLength(1). Rank è il numero di dimensioni. Tre dimensioni funzionano allo stesso modo: new int[4, 4, 4] e cube[x, y, z]. Un foreach su un array 2D visita tutti gli elementi riga per riga.
Jagged array (array di array)
Un jagged array int[][] è un array i cui elementi sono a loro volta array, e ogni array interno può avere una lunghezza propria. È adatto a dati come "ordini per cliente", in cui le righe hanno dimensioni diverse.
Output:
Customer 0: 2 orders, 20, 35
Customer 1: 1 orders, 12
Customer 2: 4 orders, 8, 15, 40, 22
True
new int[3][] crea solo l'array esterno; ogni riga parte da null, e orders[0][0] prima di assegnare una riga lancia NullReferenceException. La sintassi new int[3][4] non è ammessa; ogni riga la crei tu.
Usa [,] per una vera griglia (una scacchiera, una matrice, dei pixel) e [][] quando le righe hanno lunghezze diverse o vuoi scambiare righe intere.
Array vs List
Array T[] | List<T> | |
|---|---|---|
| Dimensione | Fissata alla creazione | Cresce e si riduce |
| Numero di elementi | Proprietà Length | Proprietà Count |
| Aggiungere o rimuovere | Impossibile (solo Array.Resize) | Add, Insert, Remove |
| Multidimensionale | [,] e [][] | Solo liste di liste |
| Uso tipico | Dimensione nota, tabelle di lookup, buffer | Collezioni che cambiano |
La conversione è una sola chiamata in entrambi i sensi: new List<int>(arr) o arr.ToList(), e list.ToArray(). List<T> è la versione che può crescere.
Errori comuni
i <= arr.Lengthin un ciclo. L'ultimo indice valido èLength - 1; questo lanciaIndexOutOfRangeException.- Stampare direttamente l'array.
Console.WriteLine(arr)stampaSystem.Int32[]; usastring.Join. - Aspettarsi che
Array.Sortrestituisca l'array ordinato. Restituiscevoide ordina sul posto. - Copiare con
=. Così copi il riferimento; usaClone()oToArray(). - Usare le righe di un jagged array prima di crearle. Ogni riga di
new T[n][]ènullfinché non viene assegnata. - Usare
Lengthper le righe di un array 2D. Conta tutti gli elementi; usaGetLength(0).
Domande frequenti
Come ottengo la lunghezza di un array in C#?
Usa la proprietà Length: scores.Length. È una proprietà, non un metodo, quindi niente parentesi. In un array 2D Length è il numero totale di elementi; usa GetLength(0) per il numero di righe e GetLength(1) per il numero di colonne.
Come ordino un array in C#?
Array.Sort(arr) ordina l'array sul posto in ordine crescente. Per l'ordine decrescente chiama Array.Reverse(arr) dopo l'ordinamento, oppure passa un confronto: Array.Sort(arr, (a, b) => b.CompareTo(a)). Per ottenere una copia ordinata e conservare l'originale usa LINQ: arr.OrderBy(x => x).ToArray().
Che differenza c'è tra un array 2D e un jagged array in C#?
Un array 2D int[,] è un unico blocco rettangolare: ogni riga ha lo stesso numero di colonne e lo indicizzi con grid[row, col]. Un jagged array int[][] è un array di array: ogni riga è un array separato che può avere una lunghezza propria, e lo indicizzi con rows[i][j]. Ogni riga di un jagged array va creata prima dell'uso, altrimenti è null.
Si può cambiare la dimensione di un array in C#?
No. La lunghezza di un array è fissata quando viene creato. Array.Resize(ref arr, newSize) sembra ridimensionarlo, ma alloca un nuovo array, copia gli elementi e fa puntare la tua variabile a quello nuovo. Se la dimensione cambia spesso, usa una List<T>.
Perché stampando un array vedo System.Int32[]?
Console.WriteLine(arr) chiama arr.ToString(), e gli array non lo sovrascrivono, quindi ottieni il nome del tipo. Unisci invece gli elementi in un'unica stringa: Console.WriteLine(string.Join(", ", arr)).
Meglio un array o una List in C#?
Usa un array quando il numero di elementi è noto e fisso, come i 12 mesi o una scacchiera. Usa List<T> quando gli elementi vengono aggiunti o rimossi nel tempo. Entrambi accedono per indice in tempo costante, e una List<T> internamente conserva i suoi elementi in un array.