Come ottenere il valore enum tramite stringa o int


108

Come posso ottenere il valore enum se ho la stringa enum o il valore enum int. ad esempio: se ho un enum come segue:

public enum TestEnum
{
    Value1 = 1,
    Value2 = 2,
    Value3 = 3
}

e in alcune variabili stringa ho il valore "valore1" come segue:

string str = "Value1" 

o in qualche variabile int ho il valore 2 come

int a = 2;

come posso ottenere l'istanza di enum? Voglio un metodo generico in cui posso fornire l'enum e la mia stringa di input o il valore int per ottenere l'istanza di enum.


possibile duplicato di Get enum int value by string

Risposte:


210

No, non vuoi un metodo generico. Questo è molto più semplice:

MyEnum myEnum = (MyEnum)myInt;

MyEnum myEnum = (MyEnum)Enum.Parse(typeof(MyEnum), myString);

Penso che sarà anche più veloce.


Questo è effettivamente il modo corretto per farlo. Non esiste un modo generico per analizzare i tipi per lo stesso motivo per cui non esiste un'interfaccia IParsable.
Johannes

1
@Johannes Cosa intendi dire? C'è un modo generico, riferisci la mia risposta e anche altre.
Sriram Sakthivel

1
@SriramSakthivel Il problema descritto dall'OP è stato risolto come ha mostrato KendallFrey. L'analisi generica non può essere eseguita - vedere qui: informit.com/blogs/blog.aspx?uk=Why-no-IParseable-interface . Qualsiasi altra soluzione non ha alcun vantaggio rispetto alla soluzione "onboard" di C #. Il massimo che puoi avere è un ICanSetFromString <T> in cui crei e inizializzi un oggetto sul suo valore predefinito (T) e in un passaggio successivo passi una stringa rappresentativa. Questo è vicino alla risposta fornita dall'OP, ma è inutile perché di solito si tratta di un problema di progettazione e un punto più ampio nella progettazione del sistema è stato perso.
Johannes

Questa risposta ha funzionato molto bene, specialmente con i molteplici esempi di utilizzo di int e string. Grazie.
Termato

1
Penso che ora funzioni, è un po 'più conciso: Enum.Parse <MyEnum> (myString);
Phil B

32

Ci sono molti modi per farlo, ma se vuoi un semplice esempio, questo andrà bene. Deve solo essere migliorato con la codifica difensiva necessaria per verificare l'indipendenza dai tipi e l'analisi non valida, ecc.

    /// <summary>
    /// Extension method to return an enum value of type T for the given string.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value"></param>
    /// <returns></returns>
    public static T ToEnum<T>(this string value)
    {
        return (T) Enum.Parse(typeof(T), value, true);
    }

    /// <summary>
    /// Extension method to return an enum value of type T for the given int.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value"></param>
    /// <returns></returns>
    public static T ToEnum<T>(this int value)
    {
        var name = Enum.GetName(typeof(T), value);
        return name.ToEnum<T>();
    }

17

Potrebbe essere molto più semplice se usi i metodi TryParseo Parsee ToObject.

public static class EnumHelper
{
    public static  T GetEnumValue<T>(string str) where T : struct, IConvertible
    {
        Type enumType = typeof(T);
        if (!enumType.IsEnum)
        {
            throw new Exception("T must be an Enumeration type.");
        }
        T val;
        return Enum.TryParse<T>(str, true, out val) ? val : default(T);
    }

    public static T GetEnumValue<T>(int intValue) where T : struct, IConvertible
    {
        Type enumType = typeof(T);
        if (!enumType.IsEnum)
        {
            throw new Exception("T must be an Enumeration type.");
        }

        return (T)Enum.ToObject(enumType, intValue);
    }
}

Come notato da @chrfin nei commenti, puoi renderlo un metodo di estensione molto facilmente semplicemente aggiungendo thisprima del tipo di parametro che può essere utile.


2
Ora aggiungi anche un thisal parametro e rendilo EnumHelperstatico e puoi usarli anche come estensioni (vedi la mia risposta, ma hai un codice migliore / completo per il resto) ...
Christoph Fink

@chrfin Buona idea, ma non la preferisco in quanto apparirà in intellisense dove non è richiesto quando abbiamo spazi dei nomi nell'ambito. Sarà fastidioso immagino.
Sriram Sakthivel

1
@chrfin Grazie per il commento, aggiunto come nota nella mia risposta.
Sriram Sakthivel

5

Di seguito è riportato il metodo in C # per ottenere il valore enum dalla stringa

///
/// Method to get enumeration value from string value.
///
///
///

public T GetEnumValue<T>(string str) where T : struct, IConvertible
{
    if (!typeof(T).IsEnum)
    {
        throw new Exception("T must be an Enumeration type.");
    }
    T val = ((T[])Enum.GetValues(typeof(T)))[0];
    if (!string.IsNullOrEmpty(str))
    {
        foreach (T enumValue in (T[])Enum.GetValues(typeof(T)))
        {
            if (enumValue.ToString().ToUpper().Equals(str.ToUpper()))
            {
                val = enumValue;
                break;
            }
        }
    }

    return val;
}

Di seguito è riportato il metodo in C # per ottenere il valore enum da int.

///
/// Method to get enumeration value from int value.
///
///
///

public T GetEnumValue<T>(int intValue) where T : struct, IConvertible
{
    if (!typeof(T).IsEnum)
    {
        throw new Exception("T must be an Enumeration type.");
    }
    T val = ((T[])Enum.GetValues(typeof(T)))[0];

    foreach (T enumValue in (T[])Enum.GetValues(typeof(T)))
    {
        if (Convert.ToInt32(enumValue).Equals(intValue))
        {
            val = enumValue;
            break;
        }             
    }
    return val;
}

Se ho un'enumerazione come segue:

public enum TestEnum
{
    Value1 = 1,
    Value2 = 2,
    Value3 = 3
}

quindi posso utilizzare i metodi di cui sopra come

TestEnum reqValue = GetEnumValue<TestEnum>("Value1");  // Output: Value1
TestEnum reqValue2 = GetEnumValue<TestEnum>(2);        // OutPut: Value2

Spero che questo ti aiuti.


4
Puoi anche fornire un riferimento su dove l'hai preso?
JonH

Per compilare questo ho dovuto modificare la prima riga in public T GetEnumValue <T> (int intValue) dove T: struct, IConvertible Attenzione anche a un '}' extra alla fine
Avi

3

Penso che tu abbia dimenticato la definizione del tipo generico:

public T GetEnumValue<T>(int intValue) where T : struct, IConvertible // <T> added

e puoi migliorarlo per essere più conveniente come ad esempio:

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

allora puoi fare:

TestEnum reqValue = "Value1".ToEnum<TestEnum>();

2

Prova qualcosa di simile

  public static TestEnum GetMyEnum(this string title)
        {    
            EnumBookType st;
            Enum.TryParse(title, out st);
            return st;          
         }

Quindi puoi farlo

TestEnum en = "Value1".GetMyEnum();

2

Dal database SQL ottieni l'enumerazione come:

SqlDataReader dr = selectCmd.ExecuteReader();
while (dr.Read()) {
   EnumType et = (EnumType)Enum.Parse(typeof(EnumType), dr.GetString(0));
   ....         
}

2

Prova semplicemente questo

È un altro modo

public enum CaseOriginCode
{
    Web = 0,
    Email = 1,
    Telefoon = 2
}

public void setCaseOriginCode(string CaseOriginCode)
{
    int caseOriginCode = (int)(CaseOriginCode)Enum.Parse(typeof(CaseOriginCode), CaseOriginCode);
}

0

Ecco un esempio per ottenere stringa / valore

    public enum Suit
    {
        Spades = 0x10,
        Hearts = 0x11,
        Clubs = 0x12,
        Diamonds = 0x13
    }

    private void print_suit()
    {
        foreach (var _suit in Enum.GetValues(typeof(Suit)))
        {
            int suitValue = (byte)(Suit)Enum.Parse(typeof(Suit), _suit.ToString());
            MessageBox.Show(_suit.ToString() + " value is 0x" + suitValue.ToString("X2"));
        }
    }

    Result of Message Boxes
    Spade value is 0x10
    Hearts value is 0x11
    Clubs value is 0x12
    Diamonds value is 0x13

0

Puoi usare il seguente metodo per farlo:

public static Output GetEnumItem<Output, Input>(Input input)
    {
        //Output type checking...
        if (typeof(Output).BaseType != typeof(Enum))
            throw new Exception("Exception message...");

        //Input type checking: string type
        if (typeof(Input) == typeof(string))
            return (Output)Enum.Parse(typeof(Output), (dynamic)input);

        //Input type checking: Integer type
        if (typeof(Input) == typeof(Int16) ||
            typeof(Input) == typeof(Int32) ||
            typeof(Input) == typeof(Int64))

            return (Output)(dynamic)input;

        throw new Exception("Exception message...");
    }

Nota: questo metodo è solo un campione e puoi migliorarlo.

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.