1. Introduzione
Quando programmi, spesso ti capita di lavorare con liste di opzioni già note e limitate. Tipo: giorni della settimana, colori del semaforo, livelli di difficoltà di un gioco, stati di un ordine. Ognuna di queste opzioni di solito è rappresentata da un valore fisso. Ed è qui che arriviamo al tema di oggi — enum (enum).
Enum — è un tipo di dato speciale che ti permette di dichiarare un set di costanti con nome.
enum — pensa a una scatola con etichette in scomparti, dove ogni etichetta è un nome unico collegato a un numero.
- Il tuo codice diventa leggibile e auto-documentato;
- Al posto di strani “numeri magici” tipo 0, 1, 2 hai nomi chiari: DayOfWeek.Monday o TrafficLight.Red;
- Il compilatore ti avvisa se provi a dare un valore non valido;
- Dietro ogni elemento c’è… un semplice numero intero! (Ma ci torniamo tra poco.)
2. Sintassi per dichiarare un enum
Facciamo il nostro primo enum — tipi di meteo per la nostra futura app. Ecco come si fa:
// Enum delle condizioni meteo
public enum WeatherCondition
{
Sunny, // 0
Cloudy, // 1
Rainy, // 2
Stormy, // 3
Snowy // 4
}
- La parola chiave enum crea un nuovo tipo.
- Tra le parentesi graffe ci sono i nomi delle opzioni. Di default, ogni opzione ha un numero intero a partire da zero (Sunny == 0, Cloudy == 1 ecc.).
- Puoi anche assegnare valori espliciti:
public enum WeatherCondition
{
Sunny = 1,
Cloudy = 2,
Rainy = 4,
Stormy = 8,
Snowy = 16
}
Comodo se i valori devono rispettare qualche standard esterno o protocollo.
3. Usare gli enum
Immagina di aver scritto una piccola app console che reagisce al meteo.
// Classe dell'app
class Program
{
static void Main()
{
// Usiamo il nostro enum per salvare lo stato del meteo
WeatherCondition todayWeather = WeatherCondition.Sunny;
// Stampiamo a schermo
Console.WriteLine($"Oggi il meteo è: {todayWeather} ({(int)todayWeather})");
// Simuliamo un cambio di meteo
todayWeather = WeatherCondition.Rainy;
Console.WriteLine($"Ops! Il meteo è cambiato: {todayWeather} ({(int)todayWeather})");
}
}
Cosa succede?
Oggi il meteo è: Sunny (0)
Ops! Il meteo è cambiato: Rainy (2)
- todayWeather — non è una stringa, né un numero, ma un elemento enum.
- Il cast a (int) ti fa vedere il “codice numerico” di quel valore.
Tra l’altro, gli enum vanno alla grande con le condizioni:
if (todayWeather == WeatherCondition.Rainy)
Console.WriteLine("Prendi l'ombrello!");
4. Scenari pratici per usare gli enum
Dove trovi gli enum?
- In app business: stati di un ordine (New, Processing, Shipped, Cancelled).
- In sistemi di gestione utenti: livelli di accesso (User, Moderator, Admin).
- Nei giochi: stati del personaggio (Idle, Moving, Jumping, Falling).
- Nel GUI: bottoni, messaggi, colori delle icone.
E se vai a fondo in .NET — li trovi praticamente in ogni secondo classe della libreria standard! Per esempio, nelle operazioni sui file ci sono enum per specificare la modalità di apertura (lettura, scrittura, creazione).
5. Valori espliciti e range di valori
A volte vuoi convertire un set di valori int che usi nel codice in un enum. È facilissimo:
public enum CompassDirection
{
North = 10,
East = 20,
South = 30,
West = 40
}
Ora CompassDirection.North = 10, East = 20, ecc. Se non specifichi un valore, prende automaticamente il valore precedente +1.
Tipo di storage
Di default, un enum viene salvato come int (intero a 4 byte). Ma puoi specificare il tipo base se vuoi risparmiare memoria:
public enum TinyEnum : byte
{
First, // 0
Second, // 1
Third // 2
}
Ora ogni valore dell'enum occupa solo un byte!
Lista completa dei tipi possibili: byte, sbyte, short, ushort, int, uint, long, ulong.
6. Conversione tra enum e numeri/stringhe
Conversione enum ↔ int:
Per convertire un enum in int e viceversa, basta usare il cast:
WeatherCondition current = WeatherCondition.Cloudy;
int number = (int)current; // Ottieni 1
WeatherCondition fromNumber = (WeatherCondition)2; // Ottieni Rainy
Conversione enum ↔ string:
Convertire un enum in stringa è facile: basta chiamare il metodo ToString().
// Convertiamo enum in stringa
string name = WeatherCondition.Stormy.ToString(); // "Stormy"
// Convertiamo stringa in enum con Enum.Parse
WeatherCondition parsed = (WeatherCondition)Enum.Parse(typeof(WeatherCondition), "Stormy");
// Puoi anche usare Enum.TryParse
WeatherCondition parsedOk;
if (Enum.TryParse("Snowy", out parsedOk))
{
Console.WriteLine(parsedOk); // Snowy
}
Errore tipico:
Se fai il cast di un numero a enum che non ha quel membro, il compilatore non si lamenta, ma ottieni uno stato "virtuale".
Per esempio:
WeatherCondition weird = (WeatherCondition)999;
Console.WriteLine(weird); // 999 (non diventa "Unknown"!)
Quindi, occhio quando fai queste conversioni.
7. switch e enum sono fatti l’uno per l’altro
Gli enum (enum) vanno a nozze con lo statement switch. È un modo super comodo e chiaro per “reagire” ai diversi valori dell’enum — senza mille “if-else”.
Esempio: reazione al meteo
public enum WeatherCondition
{
Sunny,
Cloudy,
Rainy,
Stormy,
Snowy
}
WeatherCondition today = WeatherCondition.Rainy;
switch (today)
{
case WeatherCondition.Sunny:
Console.WriteLine("Sole! Si può andare a fare una passeggiata.");
break;
case WeatherCondition.Cloudy:
Console.WriteLine("Nuvoloso. Meglio portarsi una felpa.");
break;
case WeatherCondition.Rainy:
Console.WriteLine("Sta piovendo. Non dimenticare l'ombrello!");
break;
case WeatherCondition.Stormy:
Console.WriteLine("Tempesta! Meglio restare a casa.");
break;
case WeatherCondition.Snowy:
Console.WriteLine("Nevica — metti il cappello!");
break;
default:
Console.WriteLine("Meteo sconosciuto...");
break;
}
- Ogni case corrisponde a un valore dell’enum.
- Se il valore non corrisponde a nessuna delle opzioni note, parte il default (utile se qualcuno ha fatto un cast strano).
Perché enum + switch è una combo top?
- Codice leggibile: vedi subito tutte le opzioni nei case.
- Facile da estendere: aggiungi un nuovo tipo di meteo — basta un altro case.
- Sicurezza: il compilatore ti avvisa se ti dimentichi qualche opzione (da C# 8.0 puoi anche attivare il check per la copertura completa).
Esempio: enum con logica per un gioco
public enum GameState
{
Start,
Playing,
Paused,
GameOver
}
void PrintState(GameState state)
{
switch (state)
{
case GameState.Start:
Console.WriteLine("Benvenuto nel gioco!");
break;
case GameState.Playing:
Console.WriteLine("Il gioco è in corso. Buona fortuna!");
break;
case GameState.Paused:
Console.WriteLine("Pausa. Puoi riposarti un attimo.");
break;
case GameState.GameOver:
Console.WriteLine("Gioco finito. Riprova!");
break;
default:
Console.WriteLine("Stato del gioco sconosciuto.");
break;
}
}
Consigli:
- Se hai tante azioni simili per più opzioni, puoi unirle:
switch (today)
{
case WeatherCondition.Rainy:
case WeatherCondition.Stormy:
Console.WriteLine("Non dimenticare l'ombrello e vestiti caldi!");
break;
}
- Non dimenticare il default, così gestisci anche valori strani (tipo se qualcuno fa un cast diretto da numero).
- Con switch puoi costruire “state machine”, menu e sistemi con opzioni fisse in modo super comodo.
8. Enum e metodi/servizi base di .NET
.NET ti dà un sacco di metodi utili per lavorare con gli enum:
- Enum.GetNames(typeof(WeatherCondition)) — ottieni tutti i nomi.
- Enum.GetValues(typeof(WeatherCondition)) — tutti i valori.
- Enum.IsDefined(typeof(WeatherCondition), "Rainy") — controlla se l’enum ha quel membro.
- Documentazione: System.Enum
Esempio: stampa tutte le opzioni del meteo:
foreach (var name in Enum.GetNames(typeof(WeatherCondition)))
{
Console.WriteLine(name);
}
9. Errori comuni e “trappole”
- Usano “numeri magici” invece degli enum, perdendo leggibilità.
- Non gestiscono valori non definiti nell’enum (vedi il discorso sul cast da numero).
- Danno nomi senza senso agli elementi (Value1, Value2... — e nessuno si ricorda più cosa vogliono dire).
- Violano il principio di responsabilità unica — usano un enum per cose troppo diverse tra loro.
La soluzione migliore: usa sempre gli enum quando hai un set finito di opzioni, e dai ai membri nomi chiari e autoesplicativi.
GO TO FULL VERSION