Menu

Stringhe in C#: Length, confronto, escape, stringhe verbatim e multiriga

Come funzionano le stringhe in C#: immutabilità, Length e indicizzazione, confronto con ==, Equals e string.Compare, caratteri di escape, stringhe verbatim con @ e testo multiriga, raw string literal, controlli su null e stringa vuota, e cicli sui caratteri.

Questa pagina include editor eseguibili: modifica, esegui e vedi subito l'output.

In C# una string è una sequenza di caratteri UTF-16 (valori char). È un tipo riferimento, ma si comporta come un valore negli aspetti che contano: è immutabile, e == confronta il testo invece dell'identità dell'oggetto. string è la parola chiave di C# per il tipo .NET System.String; i due sono intercambiabili.

Output:

Porto
5
0
*****
hi
Porto has 5 letters

Le stringhe sono immutabili

Nessun metodo modifica una stringa sul posto. ToUpper, Replace, Trim e ogni altro metodo restituiscono una nuova stringa e lasciano intatta quella originale. Dimenticarsi di usare il valore restituito è un bug molto comune con le stringhe:

Output:

[  maya  ]
[MAYA]
tea
tea and cake

L'immutabilità rende le stringhe sicure da condividere tra thread e da usare come chiavi di dizionario. Il prezzo è che costruire una stringa pezzo per pezzo in un ciclo crea una nuova stringa a ogni passo; in quel caso usa StringBuilder.

Length e indicizzazione

Length è una proprietà (niente parentesi). L'indicizzatore s[i] restituisce il char alla posizione i, contando da 0, ed è di sola lettura:

Output:

7
A
1
IndexOutOfRangeException
XB-2931

C# 8 e successivi accettano anche un indice dalla fine: code[^1] è l'ultimo carattere, come code[code.Length - 1]. Per prendere più caratteri insieme, vedi substring.

Length conta le unità di codice UTF-16, non quello che un lettore vede come caratteri. La maggior parte delle lettere nella maggior parte delle lingue è una sola unità, ma le emoji e alcune scritture rare ne usano due (una coppia surrogata), quindi "👍".Length vale 2.

Confrontare le stringhe

== e != confrontano i caratteri, distinguendo maiuscole e minuscole. Per tutto il resto, passa un valore StringComparison che dice come confrontare:

Output:

False
False
True
True
apple first
True
False
False
True

Quale confronto usare:

  • Ordinal confronta i codici numerici dei caratteri. È veloce, prevedibile e uguale su ogni macchina. Usalo per identificatori, nomi di file, chiavi, valori di protocollo e tutto ciò che non viene mostrato a una persona.
  • OrdinalIgnoreCase è lo stesso, ma ignora maiuscole e minuscole. È la scelta giusta per i controlli che non distinguono maiuscole e minuscole, come le estensioni dei file o gli header HTTP.
  • CurrentCulture (e CurrentCultureIgnoreCase) segue le regole della lingua dell'utente, quindi ordina le parole come farebbe un dizionario in quella lingua. Usalo per ordinare elenchi mostrati agli utenti.
  • InvariantCulture usa regole basate sulla cultura che non dipendono dalle impostazioni della lingua dell'utente. Dipende comunque dalla libreria di globalizzazione: il .NET moderno usa ICU, .NET Framework usa NLS di Windows, e i due possono ordinare alcune stringhe in modo diverso.

string.Compare(a, b) e a.CompareTo(b) senza uno StringComparison usano la cultura corrente, per cui i loro risultati cambiano da una macchina all'altra. Evita di confrontare con a.ToLower() == b.ToLower(): alloca due nuove stringhe e dà risposte sbagliate in alcune culture (la i turca con e senza punto è il caso classico).

Chiamare a.Equals(b) quando a è null lancia una NullReferenceException, mentre a == b e il metodo statico string.Equals(a, b) gestiscono il null in modo sicuro.

Caratteri di escape

Dentro un normale letterale stringa, un backslash inizia una sequenza di escape:

EscapeSignificato
\nA capo (line feed)
\rRitorno carrello
\tTabulazione
\\Backslash
\"Virgolette doppie
\'Apice singolo (serve solo in un letterale char)
\0Carattere nullo
\uXXXXCarattere UTF-16 tramite codice esadecimale a 4 cifre, es. \u00e9
\U0001F44DCarattere tramite codice esadecimale a 8 cifre; sopra U+FFFF diventa due valori char
\xH a \xHHHHCarattere tramite 1 a 4 cifre esadecimali (da evitare: la lunghezza è ambigua)
\a, \b, \f, \vAvviso, backspace, form feed, tabulazione verticale
\eCarattere escape, U+001B (C# 13)

Output:

Name:	Ana
City:	Porto
She said "hi"
C:\temp\report.txt
cafe = cafe
' is a quote char

Una sequenza non riconosciuta come "\d" è un errore di compilazione (CS1009, sequenza di escape non riconosciuta), ed è quello che succede quando un percorso Windows o un'espressione regolare viene scritto come stringa normale.

Stringhe verbatim e stringhe multiriga

Mettere @ davanti a un letterale lo rende verbatim: i backslash sono caratteri letterali e la stringa può occupare più righe. L'unico escape rimasto è "", che produce una virgoletta doppia.

Output:

C:\Users\ana\Documents\notes.txt
\d{3}-\d{4}
He said "ready" and left.
Rua das Flores 12
4050-262 Porto
Portugal
first line
second line

Una stringa verbatim multiriga include tutto ciò che sta tra le virgolette, compresa l'indentazione delle righe successive, ed è per questo che di solito si scrivono attaccate al margine come sopra. Gli a capo che contiene sono quelli del file sorgente, quindi un file salvato con i fine riga di Windows produce \r\n.

C# 11 ha aggiunto i raw string literal, che risolvono entrambi i problemi. Iniziano e finiscono con tre o più virgolette doppie, non richiedono alcun escape e rimuovono l'indentazione pari a quella delle virgolette di chiusura:

// C# 11 and later
string json = """
    {
      "name": "Ana",
      "path": "C:\temp"
    }
    """;
// The 4 spaces before the closing """ are removed from every line.

Se il contenuto stesso contiene """, inizia e termina con quattro virgolette. I raw literal si combinano anche con l'interpolazione ($"""..."""); vedi interpolazione di stringhe.

Null, stringa vuota e spazi bianchi

Una variabile stringa può essere null (nessuna stringa), vuota ("", lunghezza 0) oppure contenere solo spazi bianchi. Due metodi statici controllano questi casi senza rischiare una NullReferenceException:

Output:

null    empty: True   blank: True
""      empty: True   blank: True
"   "   empty: False  blank: True
"Ana"   empty: False  blank: False
True

Per validare l'input dell'utente, string.IsNullOrWhiteSpace è quasi sempre quello che ti serve. string.Empty e "" sono lo stesso valore; quale scrivere è questione di stile.

Ciclare sui caratteri

Una stringa è enumerabile, quindi foreach visita ogni char. Il tipo char ha metodi statici per classificare i caratteri:

Output:

letters=6 digits=4 upper=1 symbols=1
!6202tesnuS

Unire stringhe

+ concatena, e funziona con qualsiasi tipo dall'altra parte (chiama ToString()). Per combinare molti valori, preferisci l'interpolazione o string.Join:

Output:

Ana Silva, 31
Ana Silva, 31
AnaSilva
tea | coffee | juice
Total: 23
Total: 5

Le ultime due righe mostrano una trappola di precedenza: + viene valutato da sinistra a destra, quindi appena il lato sinistro è una stringa, ogni + successivo è una concatenazione. Metti tra parentesi l'aritmetica dentro una concatenazione.

Domande frequenti

Come ottengo la lunghezza di una stringa in C#?

Usa la proprietà Length: "hello".Length vale 5. È una proprietà, non un metodo, quindi non ci sono parentesi. Length conta le unità di codice UTF-16, quindi un'emoji o un altro carattere fuori dal Basic Multilingual Plane conta 2. Chiamarla su una stringa null lancia una NullReferenceException.

Come confronto le stringhe in C#?

a == b confronta il testo e distingue maiuscole e minuscole. Per un'uguaglianza che le ignori usa string.Equals(a, b, StringComparison.OrdinalIgnoreCase). Per ordinare le stringhe usa string.Compare(a, b, StringComparison.Ordinal) o un confronto basato sulla cultura, che restituisce un numero negativo, zero o un numero positivo.

Come scrivo una stringa multiriga in C#?

Metti @ davanti al letterale per renderlo verbatim: può occupare più righe, i backslash sono letterali e le virgolette doppie si scrivono "". Da C# 11 in poi anche i raw string literal delimitati da """ occupano più righe, tolgono l'indentazione comune e non richiedono alcun escape. Puoi anche unire le righe con \n o Environment.NewLine.

Cos'è una stringa verbatim in C#?

Un letterale stringa preceduto da @, come @"C:\Users\ana". Le sequenze di escape non vengono elaborate, quindi un backslash è solo un backslash, e per questo è la scelta naturale per i percorsi Windows e le espressioni regolari. L'unico escape al suo interno è "" per le virgolette doppie.

Qual è la differenza tra string e String in C#?

Nessuna. string è la parola chiave di C# che fa da alias per il tipo .NET System.String, proprio come int è un alias di System.Int32. Per convenzione si usa string nelle dichiarazioni e string.IsNullOrEmpty(...) nelle chiamate statiche, ma entrambi vengono compilati esattamente nello stesso modo.

Quali caratteri di escape supporta C#?

\n a capo, \r ritorno carrello, \t tabulazione, \\ backslash, \" virgolette doppie, \' apice singolo, \0 carattere nullo, \uXXXX un carattere UTF-16 tramite codice esadecimale, \U0001F600 un carattere tramite codice a 8 cifre (diventa una coppia surrogata), \a avviso, \b backspace, \f form feed, \v tabulazione verticale, e \e (C# 13) escape. Una sequenza sconosciuta come \d è un errore di compilazione (CS1009), ed è per questo che le espressioni regolari si scrivono di solito come stringhe verbatim.

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

INIZIA