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.


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.


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>();
    }

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.


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.


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>();

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();

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

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

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

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.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.