2011-08-25 10 views
18

Stavo lavorando a un metodo di servizio Web che riceverà una serie di valori come parametro e quindi, all'interno del metodo, ho convertito i valori nell'array in valori enum e li ho memorizzati in una lista di enum. Tuttavia, quando viene passato un valore che non è enum, viene aggiunto alla lista enum senza problemi. No InvalidCastException, niente. Ho fatto un progetto di test che assomiglia a questo:C# enum array che accetta un valore errato

static class Program 
{ 
    static void Main(string[] args) 
    { 
     List<TestValues> values = new List<TestValues>() { 
      TestValues.Value1, 
      TestValues.Value2, 
      (TestValues)15 
     }; 

     foreach (var val in values) 
      Console.WriteLine(val); 

     Console.Read(); 
    } 

    enum TestValues 
    { 
     Value1 = 2, 
     Value2 = 4, 
     Value3 = 8 
    } 
} 

quando l'eseguo, l'output è:

Value1 
Value2 
15 

Per il mio servizio web, io implemento una convalida, quindi questo non sarà mai hapen affatto. Ma ... questo è strano! Non dovrebbe il tempo di esecuzione lanciare un InvalidCastException o ArgumentOutOfRangeException, o qualcosa di simile? Dal momento che ho ottenuto una lista di enum (e non di valori int), voglio che i valori siano limitati ai valori dell'enum (questo è ciò che è un enum).

Mi manca qualcosa? Si tratta di un bug .NET, un bug C# o c'è qualcosa che non conosco con enumerazioni?

+0

1 per la domanda goof – Tigran

+1

Leggere questo: [Perché colata int al valore enum non validi non buttare eccezione?] [1] [1]: http://stackoverflow.com/ questions/6413804/why-does-casting-int-to-invalid-enum-value-not-throw-exception – vinayvasyani

risposta

19

È possibile assegnare qualsiasi valore a un enum consentito dal tipo sottostante. Per impostazione predefinita, il tipo sottostante è int, quindi è possibile assegnare qualsiasi valore int allo enum.

La ragione principale di questo è perché se si dispone di un'enumerazione [Flags], si vuole per essere in grado di assegnare valori compositi:

[Flags] 
public enum MyFlags 
{ 
    A = 1, 
    B = 2 
} 

MyFlags flags = (MyFlags)3; // Equivalent to setting A and B 

Preferibilmente si era appena utilizzare i valori di enumerazione per farlo, però:

MyFlags flags = MyFlags.A | MyFlags.B; // Sets flags to 3 

E 'importante notare, ovviamente, che l'attributo [Flags] non è necessario per attivare questo incarico. Tutti gli enum hanno questa proprietà, in base alla progettazione.

Come indicato da un numero di persone, è possibile utilizzare Enum.IsDefined() per determinare se un determinato valore è valido per un dato enum. Questo dovrebbe aiutare con la tua convalida.

+0

Mi sono completamente dimenticato di '[Flags]', perché raramente lo uso. Per me, sembra un chiaro vantaggio per quell'uso, ma un po 'strano per l'uso più comune di enumerazioni. A proposito, i commenti e le altre risposte forniscono buoni collegamenti complementari all'argomento. – Raphael

1

È sempre possibile assegnare qualsiasi valore int a un enum basato su int. Questo è di progettazione, in quanto il cast sarebbe molto più lento se dovesse controllare tutti i valori legali.

+1

Non penso che la velocità sia stata il fattore decisivo qui. –

+0

@Henk: per favore, elaborati, ci sono altri fattori oltre a Flags? –

1

Per determinare se lo specificato è definito all'interno di enum, è possibile utilizzare Enum.IsDefined.

Enum.IsDefined(typeof(TestValues), 15); 
5

Sì, non esiste alcun controllo per i valori definiti quando si converte in un valore enum.

È possibile utilizzare il metodo IsDefined per controllare se viene definito un valore specifico:

if (Enum.IsDefined(typeof(TestValues), value)) ... 
Problemi correlati