2009-07-30 12 views
5

Mi chiedevo di enumerazioni C# e cosa succede con i valori duplicati. Ho creato il seguente piccolo programma per testare le cose:C# Enumerazioni e valori duplicati - pericoli?

namespace ConsoleTest 
{ 

    enum TestEnum 
    { 
     FirstElement = -1, 
     SecondElement, 
     ThirdElement, 
     Duplicate = FirstElement 
    } 

    /// <summary> 
    /// Summary description for MainConsole. 
    /// </summary> 
    public class MainConsole 
    { 
     /// <summary> 
     /// Constructor for the class. 
     /// </summary> 
     public MainConsole() 
     { 
      // 
      // TODO: Add constructor logic here 
      // 
     } 
     /// <summary> 
     /// Entry point for the application. 
     /// </summary> 
     /// <param name="args">Arguments to the application</param> 
     public static void Main(string[] args) 
     { 
      TestEnum first = TestEnum.FirstElement; 
      TestEnum second = TestEnum.SecondElement; 
      TestEnum duplicate = TestEnum.Duplicate; 

      foreach (string str in Enum.GetNames(typeof(TestEnum))) 
      { 
       Console.WriteLine("Name is: " + str); 
      } 

      Console.WriteLine("first string is: " + first.ToString()); 
      Console.WriteLine("value is: " + ((int)first).ToString()); 
      Console.WriteLine("second string is: " + second.ToString()); 
      Console.WriteLine("value is: " + ((int)second).ToString()); 
      Console.WriteLine("duplicate string is: " + duplicate.ToString()); 
      Console.WriteLine("value is: " + ((int)duplicate).ToString()); 

      TestEnum fromStr = (TestEnum)Enum.Parse(typeof(TestEnum), "duplicate", true); 
      Console.WriteLine("fromstr string is: " + fromStr.ToString()); 
      Console.WriteLine("value is: " + ((int)fromStr).ToString()); 
      if (fromStr == TestEnum.Duplicate) 
      { 
       Console.WriteLine("Duplicate compares the same as FirstElement"); 
      } 
      else 
      { 
       Console.WriteLine("Duplicate does NOT compare the same as FirstElement"); 
      } 

     } 
    } 
} 

che produce il seguente output:

Name is: SecondElement 
Name is: ThirdElement 
Name is: FirstElement 
Name is: Duplicate 
first string is: FirstElement 
value is: -1 
second string is: SecondElement 
value is: 0 
duplicate string is: FirstElement 
value is: -1 
fromstr string is: FirstElement 
value is: -1 
Duplicate compares the same as FirstElement 
Press any key to continue . . . 

Questo sembra essere esattamente quello che voglio e si aspettano dal momento che sto costruendo qualcosa che una versione il tag aumenterà di tanto in tanto, quindi voglio qualcosa che posso "assegnare" alla versione corrente e persino confrontarlo con esso.

Ecco la domanda però: quali sono le insidie ​​di questo approccio? Ce n'è uno? E 'solo cattivo stile (non voglio finire su thedailywtf)? C'è un modo molto migliore di fare qualcosa del genere? Sono su .NET 2.0 e NON ho la possibilità di andare a 3.5 o 4.0.

Le opinioni sono benvenute.

+0

Vedo che le enumerazioni vengono convertite in stringhe, Vedo una stringa che viene analizzata in una emum. Che cosa stai facendo, stai facendo correttamente, ma qual è il tuo obiettivo? –

+0

@Rob Elliott - alcune di queste cose andranno in e leggeranno da un archivio dati basato su stringhe (non è una mia scelta), quindi devo assicurarmi di recuperare ciò che mi aspetto. –

risposta

1

Non è chiaro cosa stai cercando di ottenere, ma non mi sembra perfetto. Aggiungendo un'altra voce all'enum dopo "Duplica", ad esempio, verrà preso il valore 0 a meno che non si imposti di nuovo il valore in modo esplicito.

+0

Ho provato questo, e hai assolutamente ragione. Questo può essere molto pericoloso se non stai raggruppando correttamente i tuoi valori. –

3

Non vedo nulla di sbagliato in esso e di fatto faccio la stessa cosa a volte. Ci sono momenti in cui un metodo (in particolare un P/Invoke nativo per un APi che è cresciuto nel tempo) può assumere gli stessi valori numerici, ma significano qualcosa di diverso, quindi mi piace avere un nome di valore di enumerazione che descrive l'utilizzo.

+0

Ho appena fatto qualcosa di simile con gli argomenti della riga di comando. Mi sono stancato di vedere args [2], args [3], quindi ho creato un enum per gli indici argomento, in modo da poter fornire nomi significativi.Sono arrivato a questo post perché per diversi switch di comando, un argomento allo stesso indice aveva un significato diverso, quindi ho finito per dover duplicare alcuni valori di enum. – Triynko

5

Fornire valori di enum alias può essere utile se si dispone di un enumerazione di contrassegni. Per esempio.

[Flags] 
enum Rows { 
    Even = 0x01, 
    Odd = = 0x02, 
    All = Even | Odd 
} 

Tuttavia, se si leggono le linee guida per le enumerazioni in Framework Design Guidelines da Cwalina e Abrams troverete i seguenti consigli:

NON utilizzare un enum per i set aperti (come la versione del sistema operativo, i nomi dei tuoi amici, ecc.).

e

Non includere i valori sentinella in enumerazioni.

Avere una corrente versione è un valore sentinella.

Queste linee guida sono per la progettazione della struttura e se si desidera semplicemente utilizzare l'enum internamente nella propria applicazione, potrebbe non essere importante se si rompono queste linee guida. Tuttavia, Microsoft ha creato queste linee guida per evitare errori comuni quando altri sviluppatori devono utilizzare il codice.