Le enumerazioni possono certamente rendere il codice più leggibile. Ci sono ancora alcune cose a cui prestare attenzione (almeno in .net)
Poiché l'archiviazione sottostante di un enum è un int, il valore predefinito sarà zero, quindi dovresti assicurarti che 0 sia un valore predefinito ragionevole. (Ad esempio, gli struct hanno tutti i campi impostati su zero quando vengono creati, quindi non c'è modo di specificare un valore predefinito diverso da 0. Se non hai un valore 0, non puoi nemmeno testare l'enumerazione senza eseguire il cast a int, che sarebbe cattivo stile.)
Se le tue enumerazioni sono private del tuo codice (mai esposte pubblicamente), puoi smettere di leggere qui.
Se le tue enumerazioni sono pubblicate in qualche modo in codice esterno e / o vengono salvate fuori dal programma, considera di numerarle esplicitamente. Il compilatore li numera automaticamente da 0, ma se riorganizzi le tue enumerazioni senza dare loro valori puoi finire con dei difetti.
Posso scrivere legalmente
WriteMode illegalButWorks = (WriteMode)1000000;
file.Write( data, illegalButWorks );
Per contrastare questo problema, qualsiasi codice che utilizza un'enum di cui non si può essere certi (ad esempio l'API pubblica) deve controllare se l'enum è valido. Lo fai tramite
if (!Enum.IsDefined(typeof(WriteMode), userValue))
throw new ArgumentException("userValue");
L'unico avvertimento Enum.IsDefined
è che utilizza la riflessione ed è più lento. Inoltre soffre di un problema di controllo delle versioni. Se devi controllare spesso il valore enum, faresti meglio a fare quanto segue:
public static bool CheckWriteModeEnumValue(WriteMode writeMode)
{
switch( writeMode )
{
case WriteMode.Append:
case WriteMode.OverWrite:
break;
default:
Debug.Assert(false, "The WriteMode '" + writeMode + "' is not valid.");
return false;
}
return true;
}
Il problema del controllo delle versioni è che il vecchio codice potrebbe solo sapere come gestire i 2 enumeratori che hai. Se aggiungi un terzo valore, Enum.IsDefined sarà true, ma il vecchio codice non può necessariamente gestirlo. Ops.
C'è ancora più divertimento che puoi fare con le [Flags]
enumerazioni e il codice di convalida per questo è leggermente diverso.
Noterò anche che per la portabilità, dovresti usare call ToString()
sull'enum e usarli Enum.Parse()
quando li rileggi. Entrambi ToString()
e Enum.Parse()
possono gestire anche gli [Flags]
enum, quindi non c'è motivo per non usarli. Intendiamoci, è ancora un altro trabocchetto, perché ora non puoi nemmeno cambiare il nome dell'enumerazione senza possibilmente infrangere il codice.
Quindi, a volte devi soppesare tutto quanto sopra quando ti chiedi Posso farla franca solo con un bool?