Vai al contenuto

Decisioni: if, else, switch e input sicuro

Il programma impara a scegliere: condizioni con if ed else, operatori di confronto e logici, switch, e come leggere numeri dalle TextBox senza far bloccare l'app.

Finora i tuoi programmi facevano sempre la stessa cosa: premi il bottone, esegue le istruzioni una dopo l'altra, fine. Ma un programma vero deve decidere: se il voto è almeno 6 scrive "promosso", altrimenti "non promosso"; se l'utente ha scritto lettere invece di un numero, deve avvisarlo invece di bloccarsi.

In questa lezione impari a:

  • far scegliere il programma con if, else if ed else;
  • scrivere condizioni con gli operatori di confronto (==, <, >= …) e logici (&&, ||, !);
  • usare switch quando i casi sono tanti valori precisi;
  • leggere un numero da una TextBox senza far bloccare il programma (TryParse e try/catch).

Tutti gli esempi sono in Windows Forms: un form con una o più TextBox, un Button e una Label per il risultato. Se non ricordi come si aggiungono e si rinominano i controlli, rivedi la lezione Visual Studio 2022: l'ambiente di lavoro.

La prima decisione: if

L'istruzione if (in italiano "se") esegue un blocco di codice solo se una condizione è vera.

if (condizione)
{
    // istruzioni eseguite SOLO se la condizione è vera
}
// qui il programma continua in ogni caso

Le regole da ricordare sono tre:

  1. la condizione va sempre tra parentesi tonde ( );
  2. il risultato della condizione è un bool: true (vera) o false (falsa);
  3. le istruzioni da eseguire vanno tra parentesi graffe { }. Dopo la parentesi tonda non si mette il punto e virgola.

Esempio. Sul form ci sono una TextBox txtVoto, un Button btnVerifica e una Label lblEsito. Fai doppio clic sul bottone e scrivi:

private void btnVerifica_Click(object sender, EventArgs e)
{
    int voto = int.Parse(txtVoto.Text);   // per ora supponiamo che l'utente scriva un numero

    lblEsito.Text = "";                    // cancella il risultato precedente

    if (voto >= 6)
    {
        lblEsito.Text = "Promosso!";
        lblEsito.ForeColor = Color.Green;
    }
}

Se scrivi 7 e premi il bottone compare "Promosso!". Se scrivi 4 non succede niente: la condizione voto >= 6 è falsa e il blocco tra graffe viene saltato.

Due strade: if ... else

Con else ("altrimenti") dici al programma cosa fare quando la condizione è falsa. Una delle due strade viene sempre eseguita, mai tutte e due.

              voto >= 6 ?
             /           \
          true           false
           |               |
   "Promosso!"      "Non promosso"
    (verde)            (rosso)
             \           /
         il programma continua
if (voto >= 6)
{
    lblEsito.Text = "Promosso!";
    lblEsito.ForeColor = Color.Green;
}
else
{
    lblEsito.Text = "Non promosso";
    lblEsito.ForeColor = Color.Red;
}

Tante strade: else if

Quando le possibilità sono più di due si aggiungono uno o più else if. Il programma controlla le condizioni dall'alto verso il basso ed esegue solo il primo blocco la cui condizione è vera; tutti gli altri vengono saltati. L'else finale (facoltativo) vale per "tutti gli altri casi".

if (voto >= 9)
{
    lblEsito.Text = "Ottimo";
}
else if (voto >= 7)
{
    lblEsito.Text = "Buono";
}
else if (voto >= 6)
{
    lblEsito.Text = "Sufficiente";
}
else
{
    lblEsito.Text = "Insufficiente";
}

Con voto 8: voto >= 9 è falsa, voto >= 7 è vera → scrive "Buono" e salta tutto il resto, anche se voto >= 6 sarebbe vera.

Attenzione all'ordine! Se scrivi prima if (voto >= 6) e poi else if (voto >= 9), un 10 farà scrivere "Sufficiente": la prima condizione vera vince e le altre non vengono più guardate. Con i "maggiore o uguale" si parte dal valore più alto.

Prova: segui il programma passo per passo

Scrivi un voto nel form qui sotto e premi Valuta. A destra vedi quali condizioni il programma controlla, in che ordine, e quale blocco esegue. Prova anche con 11, con abc e lasciando la casella vuota.

Form1
lblEsito

Il primo if controlla che l'utente abbia scritto davvero un numero: lo vedremo tra poco, nella parte sull'input sicuro. Il secondo usa || ("oppure"): scarta i voti fuori dall'intervallo da 1 a 10.

Gli operatori di confronto

Una condizione nasce quasi sempre da un confronto tra due valori. Il risultato è sempre true o false.

OperatoreSignificatoEsempioRisultato (con voto = 7)
==uguale avoto == 7true
!=diverso davoto != 7false
<minore divoto < 6false
>maggiore divoto > 6true
<=minore o ugualevoto <= 7true
>=maggiore o ugualevoto >= 8false

Attenzione: = e == sono due cose diverse. voto = 7 assegna 7 alla variabile; voto == 7 chiede se vale 7. In un if ci vuole sempre ==: se scrivi if (voto = 7) Visual Studio segna un errore.

Confrontare testi. Anche le stringhe si confrontano con == e !=, ma il confronto distingue maiuscole e minuscole: "Roma" == "roma" è false. Se non ti interessa la differenza, trasforma prima il testo con ToLower():

string citta = txtCitta.Text.Trim().ToLower();   // Trim() toglie gli spazi all'inizio e alla fine

if (citta == "torino")
{
    lblEsito.Text = "Sei di Torino!";
}

Gli operatori logici: && || !

Per unire più condizioni in una sola si usano gli operatori logici.

OperatoreSi leggeÈ vero quando…Esempio
&&e (AND)tutte e due le condizioni sono vereeta >= 14 && eta <= 19
||oppure (OR)almeno una delle due è veragiorno == "sabato" || giorno == "domenica"
!non (NOT)la condizione è falsa (la rovescia)!chkPrivacy.Checked
// Biglietto ridotto per chi ha meno di 14 anni OPPURE almeno 65
if (eta < 14 || eta >= 65)
{
    lblPrezzo.Text = "Biglietto ridotto: 6 €";
}
else
{
    lblPrezzo.Text = "Biglietto intero: 9 €";
}

// Iscrizione possibile solo se ha scritto il nome E ha spuntato la privacy
if (txtNome.Text != "" && chkPrivacy.Checked)
{
    MessageBox.Show("Iscrizione completata!");
}

chkPrivacy.Checked è già un bool (true se la casella è spuntata), quindi non serve scrivere chkPrivacy.Checked == true. Per dire "non spuntata" basta !chkPrivacy.Checked.

Allenati. Le variabili valgono eta = 16, voto = 7, iscritto = true. Per ogni condizione scegli se è vera o falsa.

Molti valori precisi: switch

Quando devi confrontare una sola variabile con tanti valori precisi (1, 2, 3… oppure "+", "-", "*"…), invece di una lunga fila di else if puoi usare switch.

string operazione = txtOperazione.Text;   // l'utente scrive + - * oppure /
double risultato = 0;

switch (operazione)
{
    case "+":
        risultato = a + b;
        break;
    case "-":
        risultato = a - b;
        break;
    case "*":
    case "x":                 // due case di fila: "*" e "x" fanno la stessa cosa
        risultato = a * b;
        break;
    case "/":
        risultato = a / b;
        break;
    default:                  // tutti gli altri casi (come l'else finale)
        MessageBox.Show("Operazione non valida");
        break;
}

Come funziona:

  • switch (operazione) indica quale variabile controllare;
  • ogni case valore: è una possibilità; il programma salta direttamente al case uguale al valore della variabile;
  • break; chiude il caso ed esce dallo switch;
  • default: viene eseguito se nessun case corrisponde.

Attenzione: in C# ogni case con delle istruzioni deve terminare con break (oppure return). Se lo dimentichi il programma non si compila (errore CS0163). Puoi invece mettere più case vuoti uno sopra l'altro, come "*" e "x" nell'esempio, per far fare a più valori la stessa cosa.

if o switch?

SituazioneCosa usareEsempio
Intervalli di valori (maggiore, minore…)if / else ifvoto da 9 in su, da 7 a 8…
Condizioni su variabili diverseif con && / ||nome scritto e privacy spuntata
Una variabile e tanti valori precisiswitchoperazione + - * /, giorno 1…7, menu

Input sicuro: quando l'utente non scrive un numero

Negli esempi abbiamo scritto int.Parse(txtVoto.Text). Funziona finché l'utente scrive davvero un numero. Ma se scrive abc, o lascia la casella vuota, la conversione fallisce e il programma si ferma con un errore (un'eccezione di tipo FormatException). In un programma vero non deve mai succedere.

Ci sono due modi per evitarlo.

Modo 1 (consigliato): TryParse

int.TryParse prova a convertire il testo. Non va mai in errore: restituisce true se ci riesce e false se no. Il numero convertito lo mette nella variabile scritta dopo out.

private void btnVerifica_Click(object sender, EventArgs e)
{
    int voto;

    if (int.TryParse(txtVoto.Text, out voto))
    {
        // conversione riuscita: in "voto" c'è il numero
        lblEsito.Text = "Hai scritto " + voto;
    }
    else
    {
        // conversione fallita: avvisiamo e NON andiamo avanti
        MessageBox.Show("Scrivi un numero intero, per esempio 7.");
        txtVoto.Focus();          // rimette il cursore nella casella
    }
}

Leggiamo la riga importante pezzo per pezzo:

PezzoSignificato
int.TryParse(...)"prova a trasformare in int"; per i numeri con la virgola si usa double.TryParse
txtVoto.Textil testo da convertire
out votodove mettere il risultato se la conversione riesce
il valore restituitotrue o false: per questo si scrive dentro un if

Spesso si controlla prima l'errore e si esce subito dal metodo con return, così il resto del codice resta pulito:

int voto;
if (!int.TryParse(txtVoto.Text, out voto))     // il ! vuol dire "se NON ci riesce"
{
    MessageBox.Show("Scrivi un numero intero.");
    return;                                     // esce dal metodo: il codice sotto non viene eseguito
}

if (voto < 1 || voto > 10)
{
    MessageBox.Show("Il voto deve essere tra 1 e 10.");
    return;
}

// da qui in poi "voto" è sicuramente un numero tra 1 e 10

Con double.TryParse il separatore dei decimali dipende dalle impostazioni di Windows: su un PC in italiano si scrive 7,5 con la virgola. 7.5 viene rifiutato oppure letto in modo sbagliato. Ricordalo agli utenti con un'etichetta accanto alla casella.

Modo 2: try / catch

Il secondo modo è lasciar provare la conversione e catturare l'errore se succede. Il codice "rischioso" va nel blocco try; se lì dentro si verifica un errore, il programma salta subito al blocco catch invece di bloccarsi.

try
{
    double a = Convert.ToDouble(txtA.Text);
    double b = Convert.ToDouble(txtB.Text);
    lblRisultato.Text = "Somma: " + (a + b);
}
catch (FormatException)
{
    MessageBox.Show("In tutte e due le caselle devi scrivere un numero.");
}
TryParsetry / catch
Come funzionacontrolla prima di convertireconverte e rimedia se va male
Quando usarloinput dell'utente da una TextBox (quasi sempre)operazioni che possono fallire in modi diversi: file, conversioni multiple, divisioni tra interi…
Vantaggiosai esattamente quale casella è sbagliataun solo blocco protegge più istruzioni

Le eccezioni hanno una lezione tutta loro nel percorso teorico: Gestione delle eccezioni. Per ora ti basta sapere che try/catch impedisce al programma di bloccarsi.

Gli errori più comuni

ErroreCosa succedeCorrezione
if (voto >= 6);il punto e virgola chiude l'if: il blocco sotto viene eseguito sempreniente ; dopo la parentesi
if (voto = 6)errore: = assegna, non confrontaif (voto == 6)
graffe dimenticatesenza { } l'if comanda solo la prima riga sottometti sempre le graffe, anche per una riga
else if nell'ordine sbagliatoun 10 risulta "Sufficiente"con >= parti dal valore più alto
6 <= voto <= 10errore: in C# non si scrive come in matematicavoto >= 6 && voto <= 10
"SI" == "si"false: maiuscole e minuscole contanotesto.ToLower() == "si"
int.Parse senza controllicon abc il programma si bloccaint.TryParse

Esercizi

Ogni esercizio è un nuovo progetto App Windows Forms. Rinomina sempre i controlli (txt…, lbl…, btn…) prima di fare doppio clic sul bottone.

Esercizio 1 – Pari o dispari. Una TextBox txtNumero, un bottone btnVerifica e una Label lblEsito. Il programma scrive se il numero è pari o dispari. Se l'utente non scrive un numero intero, mostra un avviso.

Suggerimento: un numero è pari se il resto della divisione per 2 è zero: numero % 2 == 0.

Mostra la soluzione
private void btnVerifica_Click(object sender, EventArgs e)
{
    int numero;
    if (!int.TryParse(txtNumero.Text, out numero))
    {
        MessageBox.Show("Scrivi un numero intero.");
        return;
    }

    if (numero % 2 == 0)
    {
        lblEsito.Text = numero + " è pari";
    }
    else
    {
        lblEsito.Text = numero + " è dispari";
    }
}

Esercizio 2 – Il biglietto del cinema. Una TextBox per l'età e una CheckBox chkStudente. Il biglietto costa 9 €; costa 6 € se la persona ha meno di 14 anni oppure almeno 65; costa 7 € agli studenti tra 14 e 25 anni compresi. L'età deve essere un numero tra 0 e 120.

Mostra la soluzione
private void btnCalcola_Click(object sender, EventArgs e)
{
    int eta;
    if (!int.TryParse(txtEta.Text, out eta) || eta < 0 || eta > 120)
    {
        MessageBox.Show("Scrivi un'età valida (da 0 a 120).");
        return;
    }

    int prezzo;
    if (eta < 14 || eta >= 65)
    {
        prezzo = 6;
    }
    else if (chkStudente.Checked && eta <= 25)
    {
        prezzo = 7;
    }
    else
    {
        prezzo = 9;
    }

    lblPrezzo.Text = "Prezzo: " + prezzo + " €";
}

Nel primo if le tre condizioni sono unite da ||: basta che una sia vera per mostrare l'avviso. Se TryParse fallisce, le altre due non vengono nemmeno controllate.

Esercizio 3 – Il giorno della settimana. L'utente scrive un numero da 1 a 7 e il programma mostra il nome del giorno (1 = lunedì). Per 6 e 7 aggiunge anche "è fine settimana!". Usa switch.

Mostra la soluzione
private void btnMostra_Click(object sender, EventArgs e)
{
    int giorno;
    if (!int.TryParse(txtGiorno.Text, out giorno))
    {
        MessageBox.Show("Scrivi un numero da 1 a 7.");
        return;
    }

    string nome;
    switch (giorno)
    {
        case 1: nome = "Lunedì"; break;
        case 2: nome = "Martedì"; break;
        case 3: nome = "Mercoledì"; break;
        case 4: nome = "Giovedì"; break;
        case 5: nome = "Venerdì"; break;
        case 6: nome = "Sabato"; break;
        case 7: nome = "Domenica"; break;
        default: nome = "Giorno non valido"; break;
    }

    if (giorno == 6 || giorno == 7)
    {
        nome = nome + ": è fine settimana!";
    }

    lblGiorno.Text = nome;
}

Esercizio 4 – Calcolatrice con switch. Tre TextBox: txtA, txtOperazione (l'utente scrive +, -, * o /) e txtB, un bottone = e una Label per il risultato. Usa double.TryParse per i numeri e uno switch per l'operazione. Attenzione: la divisione per zero va impedita con un messaggio.

Mostra la soluzione
private void btnUguale_Click(object sender, EventArgs e)
{
    double a, b;
    if (!double.TryParse(txtA.Text, out a) || !double.TryParse(txtB.Text, out b))
    {
        MessageBox.Show("Scrivi due numeri (per i decimali usa la virgola).");
        return;
    }

    double risultato;
    switch (txtOperazione.Text.Trim())
    {
        case "+":
            risultato = a + b;
            break;
        case "-":
            risultato = a - b;
            break;
        case "*":
            risultato = a * b;
            break;
        case "/":
            if (b == 0)
            {
                MessageBox.Show("Non si può dividere per zero.");
                return;
            }
            risultato = a / b;
            break;
        default:
            MessageBox.Show("Operazione non valida: usa + - * oppure /");
            return;
    }

    lblRisultato.Text = risultato.ToString();
}

Nel caso "/" c'è un if dentro lo switch: si possono annidare liberamente. return esce dal metodo, quindi chiude anche lo switch e non serve il break.

Esercizio 5 – Accesso con password (sfida). Due TextBox, utente e password (per nascondere i caratteri imposta la proprietà UseSystemPasswordChar a True). Se utente è admin (maiuscole e minuscole indifferenti) e password è Levi2026, la Label diventa verde con "Accesso consentito"; altrimenti rossa con "Credenziali errate". Se una delle due caselle è vuota, avvisa prima ancora di controllare.

Mostra la soluzione
private void btnAccedi_Click(object sender, EventArgs e)
{
    string utente = txtUtente.Text.Trim().ToLower();
    string password = txtPassword.Text;

    if (utente == "" || password == "")
    {
        MessageBox.Show("Compila tutti e due i campi.");
        return;
    }

    if (utente == "admin" && password == "Levi2026")
    {
        lblEsito.Text = "Accesso consentito";
        lblEsito.ForeColor = Color.Green;
    }
    else
    {
        lblEsito.Text = "Credenziali errate";
        lblEsito.ForeColor = Color.Red;
    }
}

La password non passa da ToLower(): lì maiuscole e minuscole devono contare.

Riepilogo

StrumentoA cosa serve
if (condizione) { }esegue un blocco solo se la condizione è vera
else / else ifla strada alternativa; vince la prima condizione vera
== != < > <= >=confrontano due valori e danno true o false
&& || !e, oppure, non: uniscono o rovesciano le condizioni
switch / case / break / defaultuna variabile confrontata con tanti valori precisi
int.TryParse / double.TryParseconvertono il testo senza bloccare il programma
try { } catch { }catturano un errore invece di far fermare l'app
returnesce subito dal metodo (utile dopo un avviso)

📚 Teoria collegata (percorso C# – il linguaggio, esempi in console): Strutture di controllo e Gestione delle eccezioni.