web-dev-qa-db-fra.com

Valeur d'énumération numérique C # sous forme de chaîne

J'ai l'énumération suivante:

public enum Urgency {
    VeryHigh = 1,
    High     = 2,
    Routine  = 4
}

Je peux récupérer un enum "valeur" comme chaîne comme ceci:

((int)Urgency.Routine).ToString() // returns "4"  

Remarque: Ceci est différent de:

Urgency.Routine.ToString() // returns "Routine"
(int)Urgency.Routine       // returns 4

Existe-t-il un moyen de créer une classe d'extension, ou une classe d'utilité statique, qui fournirait du sucre syntaxique? :)

55
David Moorhouse

Vous devriez juste pouvoir utiliser les surcharges de la méthode Enums ToString pour lui donner une chaîne de format, cela affichera la valeur de l'énumération sous forme de chaîne.

public static class Program
{
    static void Main(string[] args)
    {
        var val = Urgency.High;
        Console.WriteLine(val.ToString("D")); 
    }
}

public enum Urgency 
{ 
    VeryHigh = 1,
    High = 2,
    Low = 4
}
101
Scott Bartlett

Afin d'obtenir des descriptions plus "lisibles par l'homme" pour les énumérations (par exemple, "très élevé" plutôt que "très élevé" dans votre exemple), j'ai décoré les valeurs d'énumération avec l'attribut comme suit:

public enum MeasurementType
{
    Each,

    [DisplayText("Lineal Metres")]
    LinealMetre,

    [DisplayText("Square Metres")]
    SquareMetre,

    [DisplayText("Cubic Metres")]
    CubicMetre,

    [DisplayText("Per 1000")]
    Per1000,

    Other
}


public class DisplayText : Attribute
{

    public DisplayText(string Text)
    {
        this.text = Text;
    }


    private string text;


    public string Text
    {
        get { return text; }
        set { text = value; }
    }
}

Ensuite, utilisé une méthode d'extension comme celle-ci:

    public static string ToDescription(this Enum en)
    {

        Type type = en.GetType();

        MemberInfo[] memInfo = type.GetMember(en.ToString());

        if (memInfo != null && memInfo.Length > 0)
        {

            object[] attrs = memInfo[0].GetCustomAttributes(
                                          typeof(DisplayText),

                                          false);

            if (attrs != null && attrs.Length > 0)

                return ((DisplayText)attrs[0]).Text;

        }

        return en.ToString();

    }

Vous pouvez alors simplement appeler

myEnum.ToDescription ()
23
Stuart Helwig

Si vous souhaitez traiter uniquement de cette énumération, utilisez la solution de Mark Byer.

Pour une solution plus générale:

public static string NumberString(this Enum enVal) 
{
    return Convert.ToDecimal(enVal).ToString("0");
}

La conversion en décimal signifie que vous n'avez pas besoin de traiter explicitement les 8 différents types d'intégrale sous-jacents autorisés, car tous convertissent sans perte en décimal mais pas entre eux (ulong et long ne se convertissent pas sans perte entre eux mais les deux peuvent gérer tout le reste). Cela serait probablement plus rapide (surtout si vous choisissez bien dans votre ordre de comparaison), mais beaucoup plus verbeux pour un gain relativement faible.

Modifier:

Ce qui précède n'est pas aussi bon que celui de Frankentosh, Frankentosh a vu à travers la question le vrai problème et le résout très éloquemment.

4
Jon Hanna

Que diriez-vous d'un petit reflet? Devrait fonctionner avec tous les types sous-jacents.

public static class EnumTools
{
    public static string ToRawValueString(this Enum e)
    {
        return e
            .GetType()
            .GetFields(BindingFlags.Public | BindingFlags.Static)
            .First(f => f.Name==e.ToString())
            .GetRawConstantValue()
            .ToString();
    }
}

Ensuite:

Console.WriteLine(Urgency.High.ToRawValueString()); //Writes "2"
3
spender

Très bien ... J'ai maintenant ajouté une méthode d'extension à mon projet

public static class EnumExtensions 
{ 
    public static string NumberString(this Enum enVal) 
    { 
        return enVal.ToString("D"); 
    }
} 

Maintenant, je peux obtenir la valeur int - sous forme de chaîne - en appelant Urgency.Routine.NumberString(); Merci à Frankentosh et Jon :)

3
David Moorhouse

Si vous le souhaitez, vous pouvez faire fonctionner la méthode d'extension pour toutes les énumérations:

public static string ToValueString(this Enum enumValue) 
{
    if (enumValue.GetType().GetEnumUnderlyingType() == typeof(int))
        return ((int)(object)enumValue).ToString();
    else if (enumValue.GetType().GetEnumUnderlyingType() == typeof(byte))
        return ((byte)(object)enumValue).ToString();
    ... 
}        
2
Kirk Woll

Vous pouvez écrire une méthode d'extension pour votre type spécifique:

public static class UrgencyExtension
{
    public static string ToIntegerString(this Urgency u)
    {
        return ((int)u).ToString();
    }
}

Utilisez comme suit:

Urgency u = Urgency.Routine;
string s = u.ToIntegerString();
2
Mark Byers

une approche simple

((Urgency)4).ToString() // returns "Routine"
1
Lauda Wang