Ottieni il valore int da enum in C #


1825

Ho una classe chiamata Questions(plurale). In questa classe c'è un enum chiamato Question(singolare) che assomiglia a questo.

public enum Question
{
    Role = 2,
    ProjectFunding = 3,
    TotalEmployee = 4,
    NumberOfServers = 5,
    TopBusinessConcern = 6
}

Nella Questionsclasse ho una get(int foo)funzione che restituisce un Questionsoggetto per quello foo. C'è un modo semplice per ottenere il valore intero dall'enum in modo che io possa fare qualcosa del genere Questions.Get(Question.Role)?


31
Per il contrario: cast-int-to-enum-in-c-sharp .
nawfal,

11
So che sono in ritardo alla festa, ma invece di definire il tuo metodo come get(int foo)puoi definirlo come get(Question foo)fai il tuo casting all'interno del metodo, puoi chiamare il tuo metodo comeQuestions.Get(Question.Role)
Joe

Risposte:


2354

Basta lanciare l'enum, ad es

int something = (int) Question.Role;

Quanto sopra funzionerà per la stragrande maggioranza degli enum che vedi in natura, come è il tipo di base predefinito per un enum int.

Tuttavia, come cecilphillip sottolinea, enumerazioni possono avere diversi tipi sottostanti. Se un enum è dichiarata come uint, longo ulong, deve essere gettato al tipo di enum; ad es. per

enum StarsInMilkyWay:long {Sun = 1, V645Centauri = 2 .. Wolf424B = 2147483649};

dovresti usare

long something = (long)StarsInMilkyWay.Wolf424B;

23
@Harry non è vero. È possibile creare l'Enumerazione senza casting, non è necessario. e assegno il numero solo in casi speciali, il più delle volte lo lascio come valore predefinito. ma puoi fare enum Test { Item = 1 }e vedere che 1 == (int)Test.Itemè uguale.
Jaider,

33
@Jaider (int)Test.ItemQuello è un cast! () è l'operatore di cast esplicito.
Sinthia V,

48
@Sinthia V ha detto che puoi crearlo senza casting, il che è corretto
Paul Ridgway,

7
Se il tipo sottostante per enum Questionnon fosse, intma longquesto cast troncerà Roleil valore integrale!
quaylar,

1
Quando si accetta un Enumcome parametro, si sa che è solo un numero fisso di possibili valori integrali che è possibile ottenere. D'altra parte, se prendi semplicemente un int, devi confermare se questo intrientra nei valori accettati, complicando così il codice. Puoi sempre sostituire le tue firme come `` `MyMethod void pubblico (int x) {// fai qualcosa con x} MyMethod void pubblico (Enum x) {this.MyMethod ((int) x); } `` ``
percebus

307

Poiché Enums può essere qualsiasi tipo integrale ( byte, int, short, ecc), un modo più robusto per ottenere il valore integrale sottostante dell'enumerazione sarebbe quello di utilizzare il GetTypeCodemetodo unitamente con la Convertclasse:

enum Sides {
    Left, Right, Top, Bottom
}
Sides side = Sides.Bottom;

object val = Convert.ChangeType(side, side.GetTypeCode());
Console.WriteLine(val);

Questo dovrebbe funzionare indipendentemente dal tipo integrale sottostante.


32
Questa tecnica mi è valsa la pena quando ho a che fare con un tipo generico in cui T: enum (in realtà T: struct, IConvertible ma questa è una storia diversa).
aboy021

1
Come lo modifichereste per stampare il valore esadecimale di side? Questo esempio mostra il valore decimale. Il problema è che varè di tipo object, quindi è necessario decomprimerlo e diventa più disordinato di quanto vorrei.
Mark Lakata,

2
Penso che dovresti cambiare l'esempio in object val = Convert...etcquello che varsarà sempre nel tuo esempio object.
Maglia

2
@TimAbell Tutto quello che posso davvero dire è che abbiamo scoperto che le pagine ASPX compilate dinamicamente (dove devi distribuire i file .cs sul server live) stavano assegnando gli interi in modo diverso a ciascun valore. Ciò significava che gli oggetti serializzati su una macchina, si stavano deserializzando con valori diversi su una macchina diversa e si stavano effettivamente corrompendo (causando ore di confusione). L'abbiamo sollevato con MS e mi sembra di ricordare che hanno detto che gli interi autogenerati non erano garantiti per essere gli stessi quando costruiti su diverse versioni di framework.
NickG

4
@TimAbell In un'occasione separata, uno sviluppatore ha eliminato un valore Enum obsoleto / inutilizzato causando la fuoriuscita di tutti gli altri valori nella sequenza. Pertanto, i nostri standard di codifica ora richiedono che gli ID siano sempre specificati in modo esplicito, altrimenti l'aggiunta / eliminazione o persino la formattazione automatica del codice (ad esempio l'ordinamento alfabetico) modificherà tutti i valori che causano il danneggiamento dei dati. Consiglio vivamente a chiunque di specificare esplicitamente tutti i numeri interi di Enum. Ciò è estremamente importante se sono correlati a valori memorizzati esternamente (database).
NickG

199

Dichiararlo come una classe statica con costanti pubbliche:

public static class Question
{
    public const int Role = 2;
    public const int ProjectFunding = 3;
    public const int TotalEmployee = 4;
    public const int NumberOfServers = 5;
    public const int TopBusinessConcern = 6;
}

E poi puoi fare riferimento come Question.Role, e valuta sempre a into qualunque cosa tu lo definisca.


31
Userei static readonly intperché le costanti sono compilate nei loro valori rigidi. Vedi stackoverflow.com/a/755693/492
Bloke CAD,

96
Questa soluzione in realtà non offre il vero vantaggio di enumerazioni fortemente tipizzate. Se volessi passare un parametro enum GameState a un metodo specifico, ad esempio, il compilatore non dovrebbe permettermi di passare alcuna variabile int come parametro.
giovedì

12
@CADBloke che è esattamente il motivo per cui dovresti usare conste non static readonlyperché ogni volta che confronti static readonlyfai una chiamata di metodo per ottenere il valore della variabile mentre con un conststai confrontando due tipi di valore direttamente.
Blockloop

3
@ brettof86 Sì, una const sarebbe più veloce, se la limitazione della compilazione non sarà mai un problema, allora va bene.
Bloke CAD,

2
@Zack Non l'ho spiegato molto bene, compilation limitationintendo dire che il valore è hardcoded quando lo compili, quindi qualsiasi modifica a quel valore richiederebbe che tutti gli assembly che lo usano debbano essere ricompilati. Sono propenso a concordare con te sull'utilizzo perché la modifica dei valori avrebbe implicazioni di vasta portata.
Bloke CAD,

87
Question question = Question.Role;
int value = (int) question;

Ne risulterà value == 2.


34
La domanda variabile temporanea non è necessaria.
Gishu,

1
Quindi qualcosa del genere Questions.Get (Convert.ToInt16 (Question.Applications))
jim

6
Puoi semplicemente lanciare in entrambe le direzioni; l'unica cosa da guardare è che gli enum non impongono nulla (il valore enum potrebbe essere 288, anche se non esiste alcuna domanda con quel numero)
Marc Gravell

@jim: No, basta lanciare il valore: Questions.Get ((int) Question.Applications);
Guffa,

1
@Gishu Potresti dire che è ... discutibile. ;)
Felix D.

79

In una nota correlata, se si desidera ottenere il intvalore da System.Enum, quindi indicato equi:

Enum e = Question.Role;

Puoi usare:

int i = Convert.ToInt32(e);
int i = (int)(object)e;
int i = (int)Enum.Parse(e.GetType(), e.ToString());
int i = (int)Enum.ToObject(e.GetType(), e);

Gli ultimi due sono semplicemente brutti. Preferisco il primo.


1
Il secondo è il più veloce però.
Johan B,

1
Come qualcuno che è abituato ad usare i Mixin nel modding di Minecraft, il secondo sembra l'ovvio vincitore.
Sollace,

40

È più facile di quanto pensi - un enum è già un int. Deve solo essere ricordato:

int y = (int)Question.Role;
Console.WriteLine(y); // Prints 2

15
Nitpick: questo enum è già un int. Altri enum potrebbero essere di tipi diversi - prova "enum SmallEnum: byte {A, B, C}"
mqp

9
Assolutamente vero. Riferimento C #: "Ogni tipo di enumerazione ha un tipo sottostante, che può essere qualsiasi tipo integrale tranne char".
Michael Petrotta,

33

Esempio:

public Enum EmpNo
{
    Raj = 1,
    Rahul,
    Priyanka
}

E nel codice dietro per ottenere il valore enum:

int setempNo = (int)EmpNo.Raj; // This will give setempNo = 1

o

int setempNo = (int)EmpNo.Rahul; // This will give setempNo = 2

Gli enumerazioni aumenteranno di 1 e sarà possibile impostare il valore iniziale. Se non si imposta il valore iniziale, verrà assegnato inizialmente come 0.


6
Questo effettivamente compilare?
Peter Mortensen,

Qualcosa che è un Raj può essere anche un Rahul o un Priyanka? I tuoi valori sono in conflitto e dovrebbero raddoppiare per essere unici, ad es. 0, 1, 2, 4, 8, ecc. Questa è la mia preoccupazione principale per gli enum.
Timothy Gonzalez,

@TimothyGonzalez in realtà conta semplicemente 1 in su se non specifichi esplicitamente il loro valore;)
derHugo

@derHugo dipende dal fatto che si presume che i valori numerici siano base 10 o base 2.
Timothy Gonzalez,

@TimothyGonzalez bene, non c'è molto da pensare ... ho solo fatto notare che per impostazione predefinita si limitano a contare fino 1a inttranne voi esplicitamente definire altrimenti
derHugo

28

Di recente mi sono convertito dall'uso di enum nel mio codice in favore dell'utilizzo invece di classi con costruttori protetti e istanze statiche predefinite (grazie a Roelof - C # Assicurare valori di enum validi - Metodo a prova di futuro ).

Alla luce di ciò, di seguito è come ora affronterei questo problema (inclusa la conversione implicita da / a int).

public class Question
{
    // Attributes
    protected int index;
    protected string name;
    // Go with a dictionary to enforce unique index
    //protected static readonly ICollection<Question> values = new Collection<Question>();
    protected static readonly IDictionary<int,Question> values = new Dictionary<int,Question>();

    // Define the "enum" values
    public static readonly Question Role = new Question(2,"Role");
    public static readonly Question ProjectFunding = new Question(3, "Project Funding");
    public static readonly Question TotalEmployee = new Question(4, "Total Employee");
    public static readonly Question NumberOfServers = new Question(5, "Number of Servers");
    public static readonly Question TopBusinessConcern = new Question(6, "Top Business Concern");

    // Constructors
    protected Question(int index, string name)
    {
        this.index = index;
        this.name = name;
        values.Add(index, this);
    }

    // Easy int conversion
    public static implicit operator int(Question question) =>
        question.index; //nb: if question is null this will return a null pointer exception

    public static implicit operator Question(int index) =>        
        values.TryGetValue(index, out var question) ? question : null;

    // Easy string conversion (also update ToString for the same effect)
    public override string ToString() =>
        this.name;

    public static implicit operator string(Question question) =>
        question?.ToString();

    public static implicit operator Question(string name) =>
        name == null ? null : values.Values.FirstOrDefault(item => name.Equals(item.name, StringComparison.CurrentCultureIgnoreCase));


    // If you specifically want a Get(int x) function (though not required given the implicit converstion)
    public Question Get(int foo) =>
        foo; //(implicit conversion will take care of the conversion for you)
}

Il vantaggio di questo approccio è che ottieni tutto ciò che avresti dall'enum, ma il tuo codice ora è molto più flessibile, quindi se dovessi eseguire diverse azioni in base al valore di Question, puoi mettere la logica in Questionse stessa (cioè nell'OO preferito moda) invece di inserire molte dichiarazioni di casi in tutto il codice per affrontare ogni scenario.


NB: Risposta aggiornata 27-04-2018 per utilizzare le funzionalità di C # 6; vale a dire espressioni di dichiarazione e definizioni del corpo di espressioni lambda. Vedi la cronologia delle revisioni per il codice originale. Ciò ha il vantaggio di rendere la definizione un po 'meno dettagliata; che era stata una delle principali lamentele riguardo all'approccio di questa risposta.


2
Immagino sia il compromesso tra cast esplicito e il codice che devi scrivere per aggirarlo. Adoro ancora l'implementazione, vorrei solo che non fosse così lungo. +1
Lankymart

3
Ho usato diversi tipi di classi strutturate in modo simile a questo. Trovo che facciano miracoli quando provano a seguire la metodologia "non farmi essere un idiota in seguito".
James Haug,

20

Se vuoi ottenere un numero intero per il valore enum che è memorizzato in una variabile, per la quale sarebbe il tipo Question, da usare ad esempio in un metodo, puoi semplicemente farlo Ho scritto in questo esempio:

enum Talen
{
    Engels = 1, Italiaans = 2, Portugees = 3, Nederlands = 4, Duits = 5, Dens = 6
}

Talen Geselecteerd;    

public void Form1()
{
    InitializeComponent()
    Geselecteerd = Talen.Nederlands;
}

// You can use the Enum type as a parameter, so any enumeration from any enumerator can be used as parameter
void VeranderenTitel(Enum e)
{
    this.Text = Convert.ToInt32(e).ToString();
}

Questo cambierà il titolo della finestra in 4, perché la variabile Geselecteerdè Talen.Nederlands. Se lo cambio Talen.Portugeese richiamo nuovamente il metodo, il testo cambierà in 3.


3
codifica in olandese. Oh caro.
WiseStrawberry,

Sfortunatamente, questo approccio offre scarse prestazioni quanto più lo usi. L'ho provato in alcuni dei miei codici e col passare del tempo, la mia applicazione è diventata sempre più lenta, con un utilizzo sempre minore della CPU. Ciò implicava che i thread stavano aspettando qualcosa - sto assumendo un qualche tipo di garbage collection, probabilmente a causa della boxe del parametro enum su ToInt32 (). Passando a un semplice int.Parse (), sono stato in grado di eliminare completamente queste scarse prestazioni e le prestazioni sono rimaste invariate, indipendentemente dalla durata del codice.
Greg,

16

Per assicurarsi che esista un valore enum e quindi analizzarlo, è anche possibile effettuare le seguenti operazioni.

// Fake Day of Week
string strDOWFake = "SuperDay";

// Real Day of Week
string strDOWReal = "Friday";

// Will hold which ever is the real DOW.
DayOfWeek enmDOW;

// See if fake DOW is defined in the DayOfWeek enumeration.
if (Enum.IsDefined(typeof(DayOfWeek), strDOWFake))
{
    // This will never be reached since "SuperDay"
    // doesn't exist in the DayOfWeek enumeration.
    enmDOW = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), strDOWFake);
}
// See if real DOW is defined in the DayOfWeek enumeration.
else if (Enum.IsDefined(typeof(DayOfWeek), strDOWReal))
{
    // This will parse the string into it's corresponding DOW enum object.
    enmDOW = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), strDOWReal);
}

// Can now use the DOW enum object.
Console.Write("Today is " + enmDOW.ToString() + ".");

14

Forse l'ho perso, ma qualcuno ha provato un semplice metodo di estensione generico?

Questo funziona alla grande per me. In questo modo puoi evitare il cast di tipi nella tua API, ma alla fine si traduce in un'operazione di modifica del tipo. Questo è un buon caso per programmare Roslyn in modo che il compilatore faccia un metodo GetValue <T> per te.

    public static void Main()
    {
        int test = MyCSharpWrapperMethod(TestEnum.Test1);

        Debug.Assert(test == 1);
    }

    public static int MyCSharpWrapperMethod(TestEnum customFlag)
    {
        return MyCPlusPlusMethod(customFlag.GetValue<int>());
    }

    public static int MyCPlusPlusMethod(int customFlag)
    {
        // Pretend you made a PInvoke or COM+ call to C++ method that require an integer
        return customFlag;
    }

    public enum TestEnum
    {
        Test1 = 1,
        Test2 = 2,
        Test3 = 3
    }
}

public static class EnumExtensions
{
    public static T GetValue<T>(this Enum enumeration)
    {
        T result = default(T);

        try
        {
            result = (T)Convert.ChangeType(enumeration, typeof(T));
        }
        catch (Exception ex)
        {
            Debug.Assert(false);
            Debug.WriteLine(ex);
        }

        return result;
    }
}

Forse perché fare (int) customFlag è meno digitare tutto e fa più o meno la stessa cosa?
Tim Keating,

Ri "Forse l'ho perso, ma qualcuno ha provato un semplice metodo di estensione generico ?" : SixOThree ha detto "Usa invece un metodo di estensione " e Bronek ha detto "Puoi farlo implementando un metodo di estensione per il tuo tipo di enum definito" .
Peter Mortensen l'

13

Un altro modo per farlo:

Console.WriteLine("Name: {0}, Value: {0:D}", Question.Role);

Si tradurrà in:

Name: Role, Value: 2

12
public enum QuestionType
{
    Role = 2,
    ProjectFunding = 3,
    TotalEmployee = 4,
    NumberOfServers = 5,
    TopBusinessConcern = 6
}

... è una bella dichiarazione.

Devi trasmettere il risultato a int in questo modo:

int Question = (int)QuestionType.Role

Altrimenti, il tipo è fermo QuestionType.

Questo livello di rigore è il modo C #.

Un'alternativa è invece utilizzare una dichiarazione di classe:

public class QuestionType
{
    public static int Role = 2,
    public static int ProjectFunding = 3,
    public static int TotalEmployee = 4,
    public static int NumberOfServers = 5,
    public static int TopBusinessConcern = 6
}

È meno elegante da dichiarare, ma non è necessario lanciarlo nel codice:

int Question = QuestionType.Role

In alternativa, potresti sentirti più a tuo agio con Visual Basic, che soddisfa questo tipo di aspettativa in molte aree.


11
int number = Question.Role.GetHashCode();

numberdovrebbe avere il valore 2.


GetHashCode è un modo per ottenere valore dalla maschera comune Enum
ThanhLD

Nota che questo è "legittimo" solo per bool*,byte , ushort, int, e uint**. GetHashCode per altri tipi modifica il valore, ad esempio alcuni bit-shift e xors. (* 1/0, ** espressi in int ovviamente). Ma tutto sommato non lo fa a meno che non sia il tuo codice privato.
AnorZaken,

10

Puoi farlo implementando un metodo di estensione per il tuo tipo enum definito:

public static class MyExtensions
{
    public static int getNumberValue(this Question questionThis)
    {
        return (int)questionThis;
    }
}

Questo semplifica ottenere il valore int del valore enum corrente:

Question question = Question.Role;
int value = question.getNumberValue();

o

int value = Question.Role.getNumberValue();

5
Bronek, quello che hai fatto è stato inventare la sintassi non informativa attraverso un metodo di estensione (non generico btw) che in realtà impiega più tempo a scrivere. Non riesco a vedere come sia meglio della soluzione originale di Tetraneutron. Non trasformiamo questo in una chat, l'aiuto è sempre il benvenuto in StackOverflow e tutti qui sono qui per aiutarti. Per favore, prendi il mio commento come critica costruttiva.
Benjamin Gruenbaum,

2
Benjamin, prima di tutto, perché hai cancellato il mio commento? Non capisco le tue decisioni, forse qualcun altro attraverso la comunità sarebbe d'accordo con il mio commento. In secondo luogo, la mia soluzione avvolge quella di Tetraneutron ed accuratamente è più facile e meno scrivere perché un IntelliSense suggerisce il metodo di estensione, quindi penso che la tua decisione non sia imparziale e rappresentativa. Vedo molte risposte simili su Stack ed è OK. Comunque uso la mia soluzione e forse ci sono alcune persone sceglierebbero la mia soluzione in futuro, ma questi punti negativi rendono più difficile da trovare. Quasi tutti sono corretti e non copiati.
Bronek,

3
@Bronek Se non mi fai il ping non ho indicazioni che tu abbia risposto. Ho fatto non cancellare il tuo commento non ho la capacità o la voglia di farlo. Probabilmente è arrivata una mod ed è stata eliminata - sei invitato a segnalarlo per l'attenzione del moderatore e chiedere perché o meglio ancora - chiedere su Meta Stack Overflow . Ho un'opinione sulla tua soluzione dal punto di vista della programmazione che è perfettamente alla mia destra - questo è ciò per cui i commenti devono cominciare, non c'è bisogno di prenderla sul personale.
Benjamin Gruenbaum,

8

Utilizzare invece un metodo di estensione:

public static class ExtensionMethods
{
    public static int IntValue(this Enum argEnum)
    {
        return Convert.ToInt32(argEnum);
    }
}

E l'uso è leggermente più bello:

var intValue = Question.Role.IntValue();

7
public enum Suit : int
{
    Spades = 0,
    Hearts = 1,
    Clubs = 2,
    Diamonds = 3
}

Console.WriteLine((int)(Suit)Enum.Parse(typeof(Suit), "Clubs"));

// From int
Console.WriteLine((Suit)1);

// From a number you can also
Console.WriteLine((Suit)Enum.ToObject(typeof(Suit), 1));

if (typeof(Suit).IsEnumDefined("Spades"))
{
    var res = (int)(Suit)Enum.Parse(typeof(Suit), "Spades");
    Console.Out.WriteLine("{0}", res);
}

seme - "10. (giochi di carte) Ciascuno dei set di un mazzo di carte distinto per colore e / o emblemi specifici, come picche, cuori, quadri o fiori di carte da gioco tradizionali anglo, ispaniche e francesi."
Peter Mortensen,

Una spiegazione del codice di esempio sarebbe in ordine ( modificando la risposta , non qui nei commenti).
Peter Mortensen l'

lo zero è generalmente riservato allo stato disinserito / sconosciuto negli enum, insolito definirlo così
Chad Grant,

6

Uso:

Question question = Question.Role;
int value = question.GetHashCode();

Ne risulterà value == 2.

Questo è vero solo se l'enum si inserisce all'interno di un int.


1
Questo è vero solo se l'enum si inserisce all'interno di un intovviamente, poiché GetHashCoderestituisce un numero intero.
RB.

5

Poiché gli enum possono essere dichiarati con più tipi primitivi, può essere utile un metodo di estensione generico per lanciare qualsiasi tipo di enum.

enum Box
{
    HEIGHT,
    WIDTH,
    DEPTH
}

public static void UseEnum()
{
    int height = Box.HEIGHT.GetEnumValue<int>();
    int width = Box.WIDTH.GetEnumValue<int>();
    int depth = Box.DEPTH.GetEnumValue<int>();
}

public static T GetEnumValue<T>(this object e) => (T)e;

4

Di seguito è riportato il metodo di estensione

public static string ToEnumString<TEnum>(this int enumValue)
{
    var enumString = enumValue.ToString();
    if (Enum.IsDefined(typeof(TEnum), enumValue))
    {
        enumString = ((TEnum) Enum.ToObject(typeof (TEnum), enumValue)).ToString();
    }
    return enumString;
}

4

Il mio hack preferito con enumerazioni int o minori:

GetHashCode();

Per un enum

public enum Test
{
    Min = Int32.MinValue,
    One = 1,
    Max = Int32.MaxValue,
}

Questo,

var values = Enum.GetValues(typeof(Test));

foreach (var val in values)
{
    Console.WriteLine(val.GetHashCode());
    Console.WriteLine(((int)val));
    Console.WriteLine(val);
}

uscite

one
1
1
max
2147483647
2147483647
min
-2147483648
-2147483648

Disclaimer:

Non funziona per enumerazioni basate su lunghe.


3

La soluzione più semplice che mi viene in mente è sovraccaricare il Get(int)metodo in questo modo:

[modifiers] Questions Get(Question q)
{
    return Get((int)q);
}

dove [modifiers]può essere generalmente lo stesso del Get(int)metodo. Se non riesci a modificare la Questionsclasse o per qualche motivo non vuoi, puoi sovraccaricare il metodo scrivendo un'estensione:

public static class Extensions
{
    public static Questions Get(this Questions qs, Question q)
    {
        return qs.Get((int)q);
    }
}

3

L'esempio che vorrei suggerire "per ottenere un valore" int "da un enum" è

public enum Sample
{
    Book = 1, 
    Pen = 2, 
    Pencil = 3
}

int answer = (int)Sample.Book;

Ora la risposta sarà 1.



2

Prova questo invece di convertire enum in int:

public static class ReturnType
{
    public static readonly int Success = 1;
    public static readonly int Duplicate = 2;
    public static readonly int Error = -1;        
}

2

In Visual Basic, dovrebbe essere:

Public Enum Question
    Role = 2
    ProjectFunding = 3
    TotalEmployee = 4
    NumberOfServers = 5
    TopBusinessConcern = 6
End Enum

Private value As Integer = CInt(Question.Role)

3
La domanda è per C #.
Ctrl S

2
Il titolo dice "Ottieni valore int da enum in C #" .
Peter Mortensen l'

0

Ho ideato questo metodo di estensione che include le funzionalità della lingua corrente. Usando dinamico, non ho bisogno di renderlo un metodo generico e specificare il tipo che mantiene l'invocazione più semplice e coerente:

public static class EnumEx
{
    public static dynamic Value(this Enum e)
    {
        switch (e.GetTypeCode())
        {
            case TypeCode.Byte:
            {
                return (byte) (IConvertible) e;
            }

            case TypeCode.Int16:
            {
                return (short) (IConvertible) e;
            }

            case TypeCode.Int32:
            {
                return (int) (IConvertible) e;
            }

            case TypeCode.Int64:
            {
                return (long) (IConvertible) e;
            }

            case TypeCode.UInt16:
            {
                return (ushort) (IConvertible) e;
            }

            case TypeCode.UInt32:
            {
                return (uint) (IConvertible) e;
            }

            case TypeCode.UInt64:
            {
                return (ulong) (IConvertible) e;
            }

            case TypeCode.SByte:
            {
                return (sbyte) (IConvertible) e;
            }
        }

        return 0;
    }

per favore no, potresti fare tutto questo in una riga Convert.Changetype (e, e.GetTypeCode ()) e recuperare un oggetto, non c'è bisogno di dinamiche o di un metodo di estensione
Chad Grant,

Non sarò d'accordo con l'utilizzo di Convert. Usare un cast sarebbe più semplice. Il mio intento era di essere in grado di convertire qualsiasi enum al suo valore senza usare un cast. Ciò consente di cambiare il tipo di enum senza dover cambiare tutti i cast associati - ma quando succede? Il metodo di estensione funziona correttamente. Tuttavia, sto riscontrando un problema in quanto, dato che è dinamico, il complier non può digitare check (apparentemente per l'intera istruzione), il che significa che il controllo del tipo si verifica durante l'esecuzione, non una buona soluzione. Penso che tornerò ai cast.
Jeff,

1
Non ho detto di usarlo oltre il cast, solo che questo codice è privo di senso e non realizza nulla, in realtà peggiora il problema. Consiglierei di rimuovere questa soluzione
Chad Grant il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.