1. Introduzione
Immagina: ordini una pizza al telefono (o tramite un'app, dai, siamo nel XXI secolo). Dai all'operatore i dettagli dell'ordine, e l'operatore ti restituisce il risultato: la pizza! Se l'operatore tace — resti affamato e niente felicità.
Così è anche con le funzioni: a volte il loro compito è solo fare qualcosa, ma spesso vuoi che la funzione ti restituisca anche qualcosa di utile, e il risultato può cambiare ogni volta a seconda dei dati in ingresso! Per esempio:
- Una funzione calcola la somma di due numeri e ti dice il risultato.
- Una funzione riceve l'età di una persona e restituisce la categoria ("bambino", "adulto", "pensionato").
- Una funzione crea una bella stringa per salutare l'utente per nome.
Valore di ritorno — è il modo in cui una funzione “passa” all'esterno il risultato del suo lavoro.
2. Firma del metodo con valore di ritorno
Nella lezione precedente abbiamo visto questo schema:
void PrintHello()
{
Console.WriteLine("Ciao!");
}
Il tipo void significa che la funzione non restituisce nulla (void vuol dire "vuoto", assenza di valore).
Ora vediamo come appare una funzione che restituisce qualcosa:
int Add(int a, int b)
{
// corpo della funzione
}
Qui int davanti al nome della funzione è il tipo di dato del valore di ritorno. Quindi, se la funzione restituisce una stringa — scrivi string, se un numero decimale — double, e così via.
La sintassi per dichiarare una funzione è così:
<tipo di ritorno> NomeMetodo(<parametri>)
{
// corpo della funzione
}
Esempi di firme diverse:
| Firma | Cosa restituisce |
|---|---|
|
Numero intero |
|
Stringa |
|
Numero decimale |
|
Valore booleano |
3. Operatore return: come restituire un risultato da una funzione
Per far funzionare tutto, non basta solo indicare il tipo giusto — bisogna insegnare alla funzione a mandare il risultato “verso l'alto”. Per questo serve l'operatore return. Con lui diciamo: ecco, restituisco questo valore, e a quel punto la funzione termina l'esecuzione (è come se "uscisse" subito).
tipo NomeMetodo(...)
{
// qualche calcolo
return valore;
}
Esempio:
int Add(int a, int b)
{
int sum = a + b;
return sum; // restituiamo la somma come risultato della funzione
}
Regola importante: il tipo del valore restituito tramite return deve essere esattamente uguale (o compatibile) con il tipo che hai indicato nella firma del metodo.
4. Esempi: scriviamo metodi che restituiscono qualcosa
Vediamo subito degli esempi! Ecco alcuni casi classici.
Esempio 1: sommare due numeri
int Add(int a, int b)
{
return a + b;
}
// Utilizzo:
int result = Add(10, 20);
Console.WriteLine("Somma: " + result); // Output: Somma: 30
Esempio 2: saluto personalizzato
string CreateGreeting(string name)
{
return "Ciao, " + name + "!";
}
// Utilizzo:
string greeting = CreateGreeting("Anna");
Console.WriteLine(greeting); // Output: Ciao, Anna!
Esempio 3: verifica della maggiore età
bool IsAdult(int age)
{
return age >= 18;
}
if (IsAdult(21))
{
Console.WriteLine("Ingresso consentito.");
}
else
{
Console.WriteLine("Spiacente, solo per adulti.");
}
// Output: Ingresso consentito.
Esempio 4: valore di ritorno e uso nelle espressioni
Console.WriteLine("Il doppio: " + MultiplyByTwo(7));
int MultiplyByTwo(int n)
{
return n * 2;
}
5. Tipo di ritorno: varietà e particolarità
In C# una funzione può restituire qualsiasi "tipo" (non solo numeri, stringhe e i classici). Ecco alcuni casi:
- Numeri interi: int, long, short — tutto semplice.
- Decimali: double, float, decimal.
- Stringhe: string.
- Booleani: bool.
- Array: int[], string[] e così via.
- Tipi reference: oggetti di classi che hai creato tu.
- void: caso speciale, quando non si restituisce nulla.
Perché il tipo di ritorno è così importante?
Il compilatore controlla severamente che tu restituisca quello che hai promesso. Se hai promesso di restituire int, ma provi a restituire una stringa o niente — ottieni un errore. Tipo un capo severo.
Esempio di errore:
int GetNumber()
{
return "42"; // Errore! Si aspettava int, non string.
}
6. Operatore return senza valore: per i metodi void
A dire il vero, nei metodi con tipo di ritorno dichiarato (tipo int, string) l'operatore return deve sempre essere seguito da un valore che vuoi restituire.
Ma! Se la funzione è dichiarata con tipo void, puoi comunque, se vuoi, usare return senza valore — per terminare subito l'esecuzione della funzione.
void PrintNumbers(int n)
{
if (n <= 0)
{
Console.WriteLine("Il numero non deve essere negativo!");
return; // Esci semplicemente dalla funzione, senza restituire nulla
}
for (int i = 1; i <= n; i++)
{
Console.WriteLine(i);
}
}
Questo può essere comodo se vuoi interrompere l'esecuzione della funzione in base a una condizione, ma non devi restituire nulla.
7. Errori tipici nell'uso di return
Ah, quante volte i principianti si rompono la testa sugli errori legati a return!
Problema n°1: manca return in una funzione che dovrebbe restituire qualcosa
int GetValue(bool flag)
{
if (flag)
return 1;
// Ops! E se flag == false?
}
// Errore: non tutti i rami del codice contengono return!
Soluzione: prevedi sempre return in tutti gli scenari di esecuzione della funzione! Per esempio:
int GetValue(bool flag)
{
if (flag)
return 1;
else
return 0;
}
Problema n°2: tipo di valore di ritorno non corrispondente
double GetMagicNumber()
{
return 42; // In teoria va bene (int può essere convertito implicitamente in double)
// Ma se la funzione restituisse int e tu restituisci una stringa — errore!
}
Regola: controlla la compatibilità dei tipi. Se hai dubbi — puoi convertire esplicitamente al tipo giusto:
return (double)42;
Problema n°3: return fuori tempo
Sappi che appena viene eseguito return, l'esecuzione del metodo si interrompe subito. Tutto quello che viene dopo non verrà mai eseguito!
int GetNumber()
{
return 5;
Console.WriteLine("Questa riga non verrà mai eseguita"); // il compilatore si lamenterà!
}
Problema n°4: return con valore in un metodo void (vietato!)
void PrintSomething()
{
return 1; // Non puoi restituire un valore da un metodo void!
}
GO TO FULL VERSION