2012-09-07 19 views
10

Qui ci sono molte domande sulla conversione delle stringhe su un valore enum. In generale, la risposta sembra qualcosa di simile le risposte sulla this question:Perché Enum.Parse() restituisce l'oggetto?

StatusEnum MyStatus = (StatusEnum) Enum.Parse(typeof(StatusEnum), "Active", true); 

Mentre questo è una risposta perfettamente ragionevole, e si può scrivere un metodo per semplificare la chiamata, non risponde alla domanda di perché Enum. Parse() restituisce un valore object anziché il valore enum appropriato. Perché devo trasmetterlo a StatusEnum?


Edit:

In sostanza, la domanda è perché è una funzione come questa non fa parte della classe Enum?

public static T Parse<T>(string value) where T: struct 
    { 
     return (T)Enum.Parse(typeof (T), value); 
    } 

Questa funzione funziona perfettamente, fa esattamente quello che ti aspetteresti. StatusEnum e = Enum.Parse<StatusEnum>("Active");.

+1

@ SpYk3HH - Le enumerazioni non hanno * valori *. Sono * sono * valori. Sono valori che hanno un normale sovraccarico per '.ToString()', ma sono ancora solo valori. – Bobson

+2

.NET 4.0+ ha ['Enum.TryParse '] (http://msdn.microsoft.com/en-us/library/dd783499 (v = vs.100)) –

+0

@ SpYk3HH un valore di un tipo enum è un numero intero che può essere associato a uno dei campi del tipo enum. La dimensione del numero intero può variare. Parse prende una stringa e restituisce un'istanza in scatola del tipo enum. Questo può essere chiuso o no. Anche la tua ultima frase non ha senso. String e Boolean hanno anche proprietà e metodi su cui lavorare. – phoog

risposta

10

Lo fa perché

  1. E precedette farmaci generici e (anche se non fosse :)
  2. vincoli generici non può essere enumerazioni (nelle lingue tradizionali NET)

Come tale, Object è l'unico tipo che funzionerà sempre con qualsiasi tipo di enum.

Restituendo oggetto, l'API è almeno funzionale, anche se è richiesto un cast.

+1

Mentre non si può dire "dove t: Enum" si può dire "dove t: struct" e almeno si eliminano i tipi di riferimento, o non si impone alcun vincolo ed evitare il cast/typeof. – Guvante

+0

Il fatto che sia antecedente ai farmaci generici non è un'esplosione. Sarebbe un cambiamento senza interruzione aggiungere la funzione che ho modificato in precedenza come un sovraccarico per il vecchio stile 'Enum.Parse()'. – Bobson

+0

@Reed - Vieni a pensarci, secondo la tua logica, Enum.TryParse () non dovrebbe esistere, ma lo fa. – Bobson

1

Il tipo effettivo dell'oggetto è effettivamente StatusEnum. Il compilatore e il codice durante la scrittura di Enum.Parse non hanno idea di cosa sarà quell'oggetto runtime al momento della scrittura del metodo. Non sarà noto fino a quando il metodo non verrà effettivamente chiamato.

3

TryParse ha tuttavia supporta un parametro di tipo:

Enum.TryParse<FooEnum>(name, true, out ret);

Pertanto, se si specifica il valore di ret come FooEnum ret;, non sarà necessario lanciare ad un FooEnum dopo; sarà del tipo corretto subito.

+0

È vero, ma ora hai bisogno di due linee di codice. Forse tre. Uno per dichiarare 'ret', questo e uno per usarlo che altrimenti non sarebbe stato necessario. Alzando così la questione del perché esiste una forma generica di 'TryParse()' e non una forma generica di 'Parse()'. – Bobson

+0

Probabilmente è semplicemente trascurato. Tuttavia potresti facilmente creare il tuo sovraccarico generico come metodo di estensione. – aevitas

+0

In realtà, non è possibile. Non è possibile estendere 'Enum', perché è una classe statica. Quindi chiameresti 'EnumExtensions.Parse()' (o qualunque cosa tu abbia chiamato la tua classe), e non ci sarebbe stato alcun vantaggio nell'essere un metodo di estensione. – Bobson

Problemi correlati