2009-10-29 28 views
18

(OK, io espongo le profondità della mia ignoranza qui, si prega di essere gentile)Impossibile convertire il tipo 'System.Enum' a int

Sfondo

Ho un metodo di che sembra (un po ') come questo:

public void AddLink(Enum enumVal) 
{ 
    string identifier = m_EnumInterpreter(enumVal); 
    AddLink(identifier); 
} 

L'EnumInterpreter è un Func < Enum, string> che è passato a quando viene creata la classe padre.

Sto usando Enum perché a questo livello non sono affari miei-non mi interessa quale enum specifico sia. Il codice chiamante utilizza solo un enum (generato) per evitare stringhe magiche.

Domanda

Se l'EnumInterpreter restituisce una stringa vuota, mi piacerebbe un'eccezione con il valore effettivo della enumVal. Ho pensato di essere in grado di trasmettere su int, ma il compilatore non ce l'ha. Che cosa sto facendo di sbagliato? (Per favore non dire "tutto").

+1

possibile duplicato di [Come convertire da System.Enum in base intero?] (Http://stackoverflow.com/questions/908543/how-to-convert-from-system-enum-to-base-integer) – nawfal

risposta

5

No, non è possibile eseguire il cast di un int perché System.Enum non è un enum, è solo la classe base per enumerazioni.

EDIT:

È possibile ottenere il valore come segue, ma è brutto:

int intVar = (int)enuYourEnum.GetType().GetField("value__").GetValue(objYourEnum); 
+7

Sì, è brutto. – Benjol

+1

Nota che questo fallirà se 'int' è * non * il tipo sottostante dell'enumerazione. –

+0

Beh, devo confessare che non lo è, è un uint, ma penso di aver trovato qualcosa che funzioni per me ... – Benjol

33

System.Enum non può essere direttamente cast Integer, ma non implementare in modo esplicito IConvertible, significa che è possibile utilizzare il seguente:

public void AddLink(Enum enumVal) 
{ 
    string identifier = m_EnumInterpreter(Convert.ToInt32(enumVal)); 
    AddLink(identifier); 
} 

Tenete presente che se il vostro Enum è in realtà utilizzando qualcosa di diverso da un intero (come ad esempio un galleggiante), perderete i dati non interi su conv ersion. O, ovviamente, sostituire la chiamata Converti con tutto ciò che sta convertendo da (se è noto)

+7

Le enumerazioni di C# non possono essere float: http://msdn.microsoft.com/it us/library/sbbt4032% 28VS.71% 29.aspx - ** Ogni tipo di enumerazione ha un tipo sottostante, che può essere di qualsiasi tipo integrale ** –

1

Varie cose qui:

1) la risposta di Ryan sembra ok, ma ... avrei preferito passare l'Enum verso il basso per l'interprete enum, in modo che tu possa fare tutto il Convert.To ... lì. Se sai che stai usando SOLO enum basati su interi, Convert.ToInt32() va bene. Altrimenti dovresti aggiungere aggiungendo riflessioni o provando/catturando altre conversioni.

2) Si può anche considerare l'utilizzo di membri della classe Enum, come .GetName(), .GetValue(), ecc. Poiché trattano direttamente con i nomi e i valori definiti indipendentemente dal tipo di enum.

3) tecnicamente non getterei l'eccezione al di fuori dell'interprete enum. Se questa condizione è generalmente vera, lancia l'eccezione dall'interprete di enum, in modo che tutti gli usi della classe possano beneficiare della convalida. Oppure potresti finire per duplicare il codice.

4) sembra che tu abbia uno sfondo C++/MFC a giudicare dal nome della variabile. Si potrebbe voler entrare in convenzioni di denominazione in stile C#, faciliterà la vita quando si utilizza/legge il codice e le biblioteche di altri popoli. Scopri StyleCop di MS per un buon addin che aiuti nella denominazione.

+0

1) in realtà è uint, ma nulla lo dice. 2) L'attuale (solo) implementazione di EnumInterpreter utilizza effettivamente Enum.GetName(), GetValue() non esiste. 3) Dato che l'EnumInterpreter può essere passato dentro/sovrascritto dall'esterno, non volevo essere troppo fiducioso. 4) Lavoro con persone con questo background, ed erano qui prima di me per decidere la convenzione di denominazione, ma darò un'occhiata al tuo suggerimento. – Benjol

+0

Sì, mi dispiace, è in realtà .GetValues ​​() –

1

Non so se includere questo nella mia domanda, o come risposta. Il problema è che non è la risposta, ma è la risposta che funziona per me.

Quello che ho scoperto, per caso mentre cercava qualcosa di diverso, è che se ho appena wodge che sulla fine di una stringa, ottengo ciò che voglio:

throw new Exception("EnumInterpreter returns empty string for enumVal=" + enumVal); 
//EnumInterpreter returns empty string for enumVal=3720116125 

realtà ho semplificato a int nella mia interrogazione , il tipo di dati reale è uint (in questa particolare istanza). Fortunatamente, dato che in realtà volevo solo la stringa, non devo preoccuparmene.

Non sono sicuro di quale degli altri tre risposte è 'giusto', in modo da votare via ...

-3

Perché non analizzare l'enum in una stringa e restituire il valore enum reale?

public enum MyEnum { Flower = 1, Tree = 2, Animal = 3 }; 

string name = MyEnum.Flower.ToString(); // returns "Flower" 

Penso .ToString() è deprecato e non sono sicuro circa il nuovo modo per farlo. Avrei pensato che la reale rappresentazione enum sarebbe stata più utile di quella int?

+1

Perché nel contesto del codice in questione, non ho accesso all'enumerazione. – Benjol

+2

Solo un sovraccarico di '.ToString()' è in realtà deprecato - l'intellisense è in realtà abbastanza fuorviante in tal senso. – tomfanning

+0

"Perché non analizzare l'enum su una stringa e restituire il valore effettivo dell'enum?" - L'Int32 sottostante è l'attuale valore enum. – bubbleking

4

provare questo ..

m_EnumInterpreter ((int) (oggetto) enumVal);

0

Capisco che questa non è probabilmente la soluzione al tuo problema esatto, ma voglio solo postare come ho risolto questo per una particolare API che stavo usando.

int result = (int) (ActualEnumType) MethodThatReturnsSystemEnumType(arg1, arg2); 

Speriamo che sia di aiuto a qualcuno. Doppio fuso FTW.

Problemi correlati