Comment obtenir une valeur d'énumération par chaîne ou entier

108

Comment puis-je obtenir la valeur enum si j'ai la chaîne enum ou enum int value. par exemple: si j'ai une énumération comme suit:

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

et dans une variable de chaîne, j'ai la valeur "value1" comme suit:

string str = "Value1" 

ou dans une variable int, j'ai la valeur 2 comme

int a = 2;

comment puis-je obtenir l'instance d'enum? Je veux une méthode générique où je peux fournir l'énumération et ma chaîne d'entrée ou valeur int pour obtenir l'instance d'énumération.

Abhishek Gahlout
la source
duplication possible de la valeur Get enum int par chaîne

Réponses:

210

Non, vous ne voulez pas de méthode générique. C'est beaucoup plus simple:

MyEnum myEnum = (MyEnum)myInt;

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

Je pense que ce sera aussi plus rapide.

Kendall Frey
la source
C'est en fait la bonne façon de procéder. Il n'existe pas de moyen générique d'analyser les types pour la même raison qu'il n'y a pas d'interface IParsable.
Johannes
1
@Johannes Que voulez-vous dire par là? Il existe un moyen générique, renvoyez ma réponse et d'autres aussi.
Sriram Sakthivel
1
@SriramSakthivel Le problème décrit par l'OP est résolu comme KendallFrey l'a montré. L'analyse générique ne peut pas être effectuée - voir ici: informit.com/blogs/blog.aspx?uk=Why-no-IParseable-interface . Toute autre solution n'a aucun avantage par rapport à la solution «embarquée» de C #. Le maximum que vous pouvez avoir est un ICanSetFromString <T> où vous créez et initialisez un objet à sa valeur par défaut (T) et dans une étape suivante, passez dans une chaîne représentative. C'est proche de la réponse donnée par l'OP - mais c'est inutile car il s'agit généralement d'un problème de conception et un point plus important dans la conception du système a été oublié.
Johannes
Cette réponse a très bien fonctionné, en particulier avec les multiples exemples d'utilisation d'un int et d'une chaîne. Merci.
Termato
1
Je pense que cela fonctionne maintenant, c'est un peu plus concis: Enum.Parse <MyEnum> (myString);
Phil B le
32

Il existe de nombreuses façons de procéder, mais si vous voulez un exemple simple, cela fera l'affaire. Il a juste besoin d'être amélioré avec le codage défensif nécessaire pour vérifier la sécurité du type et l'analyse invalide, etc.

    /// <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>();
    }
David Spenard
la source
17

Cela pourrait être beaucoup plus simple si vous utilisez les méthodes TryParseou Parseet 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);
    }
}

Comme indiqué par @chrfin dans les commentaires, vous pouvez en faire une méthode d'extension très facilement simplement en ajoutant thisavant le type de paramètre qui peut être pratique.

Sriram Sakthivel
la source
2
Maintenant, ajoutez également un thisau paramètre et rendez EnumHelperstatique et vous pouvez également les utiliser comme extensions (voir ma réponse, mais vous avez un code meilleur / complet pour le reste) ...
Christoph Fink
@chrfin Bonne idée, mais je ne préfère pas cela car il apparaîtra dans Intellisense là où il n'est pas nécessaire lorsque nous avons des espaces de noms dans la portée. Ce sera ennuyeux je suppose.
Sriram Sakthivel
1
@chrfin Merci pour le commentaire, ajouté en note dans ma réponse.
Sriram Sakthivel
5

Voici la méthode en C # pour obtenir la valeur enum par chaîne

///
/// 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;
}

Voici la méthode en C # pour obtenir la valeur enum par 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;
}

Si j'ai une énumération comme suit:

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

alors je peux utiliser les méthodes ci-dessus comme

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

J'espère que cela aidera.

Abhishek Gahlout
la source
4
Pouvez-vous également indiquer où vous l'avez obtenu?
JonH
Pour que cela compile, j'ai dû modifier la première ligne en public T GetEnumValue <T> (int intValue) où T: struct, IConvertible Méfiez-vous également d'un '}' supplémentaire à la fin
Avi
3

Je pense que vous avez oublié la définition de type générique:

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

et vous pouvez l'améliorer pour être plus pratique comme par exemple:

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

alors vous pouvez faire:

TestEnum reqValue = "Value1".ToEnum<TestEnum>();
Christoph Fink
la source
2

Essayez quelque chose comme ça

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

Alors tu peux faire

TestEnum en = "Value1".GetMyEnum();
huMpty duMpty
la source
2

À partir de la base de données SQL, obtenez une énumération comme:

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

Essayez simplement ceci

C'est une autre façon

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

public void setCaseOriginCode(string CaseOriginCode)
{
    int caseOriginCode = (int)(CaseOriginCode)Enum.Parse(typeof(CaseOriginCode), CaseOriginCode);
}
Eliahu Aaron
la source
0

Voici un exemple pour obtenir une chaîne / valeur

    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
Daniel Jeong
la source
0

Vous pouvez utiliser la méthode suivante pour ce faire:

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...");
    }

Remarque: cette méthode n'est qu'un exemple et vous pouvez l'améliorer.

Mohamad Bahmani
la source