2012-12-12 16 views
7

Sto cercando di capire alcune cose su Enums in generale e su come possono lavorare con Chars in particolare. Di seguito è riportato il mio esempio sto lavorando da:Qual è la differenza tra "Enum: Type" e semplicemente "Enum"

public enum AuditInteractionTypes 
{ 
    Authorized = 'A', 
    Created = 'C', 
    Revised = 'R', 
    Extracted = 'E', 
    Deleted = 'D' 
} 

In primo luogo, qual è la differenza tra dichiarandoli enum AuditInteractionTypes o enum AuditInteractionTypes : char

In secondo luogo, ho visto la numerosa di circa cercando di utilizzare Enums con chars e come post " fare "funziona avanti e indietro. Possibile domanda stupida, ma perché non potevo semplicemente andare avanti e indietro come un string.

Così, per esempio, Authorized = "A".

ho sto usando LINQ to SQL come il mio DAL se quello che conta se io chiedo, spero, una domanda livello più ampio non specifiche per il mio ambiente.

+2

Mente che dichiarando enumerazioni con un tipo di base di char è illegale nel linguaggio C#. – vcsjones

+2

* La derivazione * da 'char' non è valida, ma l'uso di letterali' char' per rappresentare il valore per-item è: 'enum Fruit: int { Apple = 'A', Orange = 'O', Banana = 'B' } ' –

+0

@AdamHouldsworth: quindi perché la parte': int'? Non capendolo. –

risposta

13

Detta tipo sottostante che verrà utilizzato per la memorizzazione del conteggio.

Quando si utilizza enum senza altro, viene utilizzato un int come tipo di archiviazione sottostante.

Quando si utilizza enum : <type>, utilizza quel tipo come tipo di storage sottostante.

Nel tuo caso, si sta cercando di fare il tipo di fondo di tipo char, ma non è valida, secondo the C# reference:

I tipi approvati per un enum sono byte, sbyte, insomma, ushort , int, uint, long o ulong.

Se si desidera memorizzare i valori char, sono disponibili due opzioni.

si potrebbe usare un tipo sottostante di ushort (è un unsigned interi a 16 bit come char), in questo modo:

public enum AuditInteractionTypes : ushort 
{ 
    Authorized = 'A', 
    Created = 'C', 
    Revised = 'R', 
    Extracted = 'E', 
    Deleted = 'D' 
} 

char ha una conversione implicita per ushort così le opere di cui sopra. Inoltre, puoi facilmente confrontare i due.

Se you want to use a string as the value allora vi consiglierei una classe enum -come, in questo modo:

public static class AuditInteractionTypes 
{ 
    // You can make these static readonly if they are likely to change. 
    public const string Authorized = "A"; 
    public const string Created = "C"; 
    public const string Revised = "R"; 
    public const string Extracted = "E"; 
    public const string Deleted = "D"; 
} 

Questa classe sarà quindi più o meno lo stesso aspetto come un enum e il codice allo stesso modo.

Nota, lo stesso trucco può essere eseguito con qualsiasi tipo, ma in genere questi tipi devono essere completamente immutabili. string riempie bene questa linea guida, essendo completamente immutabile (come lo sono la maggior parte dei tipi di valore di sistema e altri tipi di valore, se li hai progettati correttamente).

+0

Davvero, quindi perché tutti i post (come qui--> http://www.codeproject.com/Articles/78600/C-Enum-with-Char-Valued-Items) che illustrano i metodi di conversione avanti e indietro per Enums Char's ? Cosa mi manca? –

+0

@RefractedPaladin Char non sono tecnicamente un "tipo base" valido per un'enumerazione quando dichiarati in C#, quindi quello che stai vedendo in quell'articolo è un aggiramento. – vcsjones

+0

@RefractedPaladin - Se si desidera ottenere una stringa dal _value_ dell'enumerazione 'char', è necessario convertire il valore numerico (che è ciò che' 'char' è) in una rappresentazione stringa. – Oded

2

Il "tipo base" di un enum deve essere un tipo di valore integrale. Una stringa non si qualifica, è un tipo di riferimento.

Non utilizzare il valore predefinito (int) è in genere necessario solo quando si interpone con codice non gestito. I linguaggi C e C++ consentono inoltre di specificare le dimensioni di un enumerato utilizzando gli stessi tipi di base. Con un caso d'angolo di lunga durata utile quando si hanno molti valori di enumerazione [Flags], che consentono di distinguere fino a 64 valori di flag.

È possibile selezionare byte o cortocircuito se si sta veramente cercando di spremere i requisiti di archiviazione. Che può accelerare il codice grazie a un migliore utilizzo delle cache della CPU. Ciò in generale non risulta troppo efficace a causa dei requisiti di allineamento per altri campi di una classe o di una struttura. E puoi perdere il vantaggio della cache quando manipoli questi valori di enumerazione, come testare il loro valore o isolare una bandiera, i processori a 32 bit sono davvero come un int e pagherai per la conversione. È richiesta la profilazione.

+0

La dimensione utilizzata nelle operazioni (tipo 32 bit) non deve corrispondere alle dimensioni di archiviazione. Questo è il motivo per cui lo paghi. L'essenza del paragrafo. –

0

Rispondere a questo:

Possibile domanda stupida, ma perché non potevo semplicemente andare avanti e indietro come una stringa.

È possibile usare l'esecuzione in questo modo:

using System.ComponentModel; 

public enum AuditInteractionTypes 
{ 
    [Description("A")] Authorized, 
    [Description("C")] Created, 
    [Description("R")] Revised, 
    [Description("E")] Extracted, 
    [Description("D")] Deleted 
} 

Quindi, in pratica ogni elemento riceverà qualche valore stringa.

oppure è possibile utilizzare struct:

struct AuditInteractionTypes 
{ 
    static string Authorized = "A"; 
    static string Created = "C"; 
    static int Revised = 0; 
    static char[] Extracted = "E".ToCharArray(); //Not sure if this one is usefull 
} 
Problemi correlati