CodeGym /Corsi /C# SELF /switch-espressioni e...

switch-espressioni e nuovi pattern

C# SELF
Livello 10 , Lezione 5
Disponibile

1. Introduzione

Già sai scrivere codice così:

switch (color)
{
    case "red":
        Console.WriteLine("Fermati!");
        break;
    case "yellow":
        Console.WriteLine("Aspetta...");
        break;
    case "green":
        Console.WriteLine("Puoi andare!");
        break;
    default:
        Console.WriteLine("Che colore è questo?");
        break;
}

Ma che succede se vogliamo assegnare un valore diverso a una variabile in base al parametro di input, tipo restituire una stringa da una funzione in base a un numero? Prima delle switch-espressioni dovevi scrivere robe tipo questa:

string meaning;
switch (number)
{
    case 42:
        meaning = "Risposta alla domanda fondamentale sulla vita, l'universo e tutto quanto";
        break;
    case 7:
        meaning = "Numero fortunato";
        break;
    default:
        meaning = "Numero normale";
        break;
}

Non è proprio elegante per un linguaggio del XXI secolo, vero? Vorresti restituire subito il valore, come si fa di solito nei linguaggi funzionali.

Ed è qui che entrano in gioco le switch-espressioni — una delle feature più belle (e fresche) di C#, a partire dalla versione 8.0.

2. switch-espressioni: sintassi che ti viene voglia di abbracciare

Confrontiamo: statement e espressione
Il classico switch è uno statement ("istruzione"), mentre la switch-espressione è una expression, cioè calcola un valore che puoi subito assegnare a una variabile o restituire da un metodo.

Struttura di una switch-espressione:


var result = value switch
{
    pattern1 => expression1,
    pattern2 => expression2,
    _       => defaultExpression // "underscore" - cioè "altrimenti"
};
Sintassi di una switch-espressione

Per esempio:

int number = 42;
string meaning = number switch
{
    42 => "Risposta alla domanda fondamentale sulla vita, l'universo e tutto quanto",
    7  => "Numero fortunato",
    _  => "Numero normale"
};
Console.WriteLine(meaning); // => Risposta alla domanda fondamentale sulla vita, l'universo e tutto quanto

Tutto compatto, leggibile, niente codice chilometrico, neanche un break;.

Nota bene: l’underscore _ — serve per "prendere tutti gli altri casi", è l’analogo di default.

3. switch-espressioni e pattern: come si combinano

Qui inizia il vero divertimento. Nelle switch-espressioni puoi usare non solo valori normali, ma anche pattern: controlli su range, tipo, proprietà degli oggetti, deconstruction (spezzare un oggetto nelle sue parti), e pure combinatorial patterns (and, or, not).

Esempi di pattern nelle switch-espressioni

Pattern costanti
È quello che abbiamo già fatto sopra: confronto con 42, 7 e così via.

Range e confronti

int age = 17;
string category = age switch
{
    < 18 => "Minorenne",
    >= 18 and <= 65 => "Adulto",
    > 65 => "Anziano",
    _ => "Categoria d'età sconosciuta"
};
Console.WriteLine(category);

Tra l’altro, nota che puoi usare più condizioni insieme! C# sta diventando sempre più espressivo.

Pattern di tipo (Type Patterns)

Mettiamo che hai un oggetto che può essere di tipo diverso (tipo object value;). Puoi gestire i vari tipi così:

object value = 3.14;
string description = value switch
{
    int i => $"Numero intero: {i}",
    double d => $"Numero decimale: {d:F2}",
    string s => $"Questa è una stringa: '{s}'",
    null => "null!",
    _ => "Qualcos'altro"
};
Console.WriteLine(description); // => Numero decimale: 3.14

Pattern sulle proprietà (Property Patterns e Positional Patterns)

Da C# 8 in poi puoi controllare i valori delle proprietà direttamente nella switch-espressione.

Esempio con oggetto

public class User
{
    public string Name { get; set; }
    public int Age { get; set; }
}

User user = new User { Name = "Anna", Age = 17 };
string welcome = user switch
{
    { Age: < 18 } => $"Ciao, {user.Name}! Sei un adolescente.",
    { Age: >= 18 and <= 65 } => $"Ehi, {user.Name}! La vita adulta è fantastica.",
    { Age: > 65 } => $"Benvenuto, {user.Name}! Sei sempre il benvenuto.",
    _ => "Età sconosciuta"
};
Console.WriteLine(welcome);

Qui tra le parentesi graffe { Age: < 18 } — è un property pattern, cioè controlli solo una proprietà dell’oggetto.

4. Nuovi pattern C# 11-14

C# punta a essere compatto e flessibile. Di recente sono arrivati i combinatorial patterns: and, or, not, e sono migliorati anche i positional patterns. Vediamoli insieme.

Pattern logici: and, or, not

Puoi comporre condizioni complesse, proprio come nella logica matematica!

int temperature = 25;
string result = temperature switch
{
    < 0 => "Gelo!",
    >= 0 and < 20 => "Fresco",
    >= 20 and < 30 => "Confortevole",
    >= 30 or <= -30 => "Estremo!",
    _ => "Temperatura strana"
};

Se vuoi escludere dei casi, nessun problema:

int score = 80;
string grade = score switch
{
    >= 90 => "Ottimo",
    >= 60 and not >= 90 => "Buono",
    _ => "Scarso"
};

Deconstruction (Positional Patterns)

Se hai una struct o un record che supporta la deconstruction, C# ti permette di spezzare l’oggetto direttamente nella switch-espressione:

public record Point(int X, int Y);

Point p = new Point(10, 20);
string desc = p switch
{
    (0, 0) => "Origine degli assi",
    (var x, 0) => $"Sull'asse X, X={x}",
    (0, var y) => $"Sull'asse Y, Y={y}",
    (var x, var y) when x == y => $"Sulla diagonale: {x}",
    _ => $"Nel punto ({p.X}, {p.Y})"
};
Console.WriteLine(desc); // => Nel punto (10, 20)

5. Quando e perché usare le switch-espressioni

Nel C# moderno le switch-espressioni non sono solo una "feature cool", ma un vero modo per evitare codice prolisso, rendere il codice più compatto, facile da testare e mantenere. È fondamentale quando scrivi parser, handler di comandi, logica di business, regole di configurazione — ovunque ti serva ramificare l’esecuzione su criteri complessi, non solo su valori ma anche su tipi, range, proprietà, combinazioni.

Ai colloqui

  • Come gestiresti le diverse risposte di un utente?
  • Come faresti a restituire un valore diverso da una funzione, in base sia al tipo che al valore?
  • Come aggiungeresti nuove regole senza mille if-else?

Mostra una switch-espressione con i pattern! Così dimostri subito che conosci le nuove feature del linguaggio e hai uno stile di coding moderno.

Tabella: confronto tra switch-statement e switch-espressione

Caratteristica switch statement switch expression
Tipo statement (istruzione) expression (espressione)
Uso di break obbligatorio non serve
Può restituire un valore solo tramite variabile sì, restituisce direttamente
Può usare pattern parzialmente completamente (type, property, ecc.)
Trappola puoi dimenticare break tutti i rami devono restituire un valore

6. Errori tipici e piccole trappole

  • Chi inizia spesso si confonde tra switch-statement ("statement") e switch-espressione ("expression"). Per esempio, dimentica che nella switch-espressione non servono break; e che tutti i rami devono restituire un valore.
  • Se dimentichi il ramo _, il compilatore ti avvisa: "e se non corrisponde niente?".
  • Nella switch-espressione non puoi usare goto (e meno male!).
  • Se duplichi una condizione (tipo due pattern uguali), il compilatore non te la fa passare.
  • Occhio al tipo di valore restituito dalla switch-espressione: deve essere compatibile con la variabile a cui lo assegni.
2
Compito
C# SELF, livello 10, lezione 5
Bloccato
Semplice switch-espressione con pattern
Semplice switch-espressione con pattern
2
Compito
C# SELF, livello 10, lezione 5
Bloccato
Validazione della password per lunghezza e caratteri
Validazione della password per lunghezza e caratteri
1
Sondaggio/quiz
Costanti e parola chiave var, livello 10, lezione 5
Non disponibile
Costanti e parola chiave var
Costanti, struct, enum e switch
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION