web-dev-qa-db-fra.com

Récupère la valeur int d'énum en C #

J'ai une classe appelée Questions (pluriel). Dans cette classe, il existe une énumération appelée Question (singulier) qui ressemble à ceci.

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

Dans la classe Questions, j'ai une fonction get(int foo) qui renvoie un objet Questions pour cette foo. Existe-t-il un moyen simple d’obtenir la valeur entière de l’énumération pour pouvoir faire quelque chose comme Questions.Get(Question.Role)?

1634
jim

Il suffit de lancer l'énum, ​​par exemple.

int something = (int) Question.Role;

Ce qui précède fonctionnera pour la grande majorité des énumérations que vous voyez à l'état sauvage, car le type sous-jacent par défaut d'une énumération est int.

Cependant, comme le fait remarquer cecilphillip , les énumérations peuvent avoir différents types sous-jacents. Si une énumération est déclarée en tant que uint, long ou ulong, elle doit être convertie dans le type de l'énum; par exemple. pour

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

tu devrais utiliser

long something = (long)StarsInMilkyWay.Wolf424B;
2126
Tetraneutron

Puisque Enums peut être n’importe quel type d’intégrale (byte, int, short, etc.), un moyen plus robuste d’obtenir la valeur intégrale sous-jacente de l’énum consiste à utiliser le Méthode GetTypeCode associée à la classe Convert:

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

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

Cela devrait fonctionner quel que soit le type intégral sous-jacent.

281
cecilphillip

Déclarez-le comme une classe statique ayant des constantes publiques:

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

Et ensuite, vous pouvez le référencer en tant que Question.Role et il sera toujours considéré comme un int ou quoi que vous définissiez.

181
PablosBicicleta
Question question = Question.Role;
int value = (int) question;

Entraînera value == 2.

80
jerryjvl

Sur une note connexe, si vous voulez obtenir la valeur int de System.Enum, puis donnez e ici:

Enum e = Question.Role;

Vous pouvez utiliser:

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

Les deux derniers sont tout simplement laids. Je préfère le premier.

70
nawfal

C'est plus facile que vous ne le pensez - une enum est déjà un int. Il suffit de rappeler:

int y = (int)Question.Role;
Console.WriteLine(y); // prints 2
37
Michael Petrotta

Exemple:

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

Et dans le code derrière pour obtenir la valeur enum:

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

ou

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

Les enumens seront incrémentés de 1 et vous pourrez définir la valeur de départ. Si vous ne définissez pas la valeur initiale, elle sera initialement définie sur 0.

27
sooraj

Je me suis récemment écarté de l'utilisation d'énums dans mon code pour utiliser plutôt des classes avec des constructeurs protégés et des instances statiques prédéfinies (grâce à Roelof - C # Ensure Valeurs de l'énumération valide - Méthode Futureproof ).

À la lumière de cela, voici comment je voudrais aborder cette question (y compris la conversion implicite vers/depuis 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)
}

L'avantage de cette approche est que vous obtenez tout ce que vous auriez de l'en-tête, mais votre code est maintenant beaucoup plus flexible. Si vous devez effectuer différentes actions en fonction de la valeur de Question, vous pouvez insérer une logique dans Question lui-même (c'est-à-dire de la manière préférée OO _) par opposition à l'insertion de nombreuses instructions case dans votre code pour traiter chaque scénario.


NB: Réponse mise à jour le 2018-04-27 pour utiliser les fonctionnalités C # 6; c'est-à-dire des expressions de déclaration et des définitions de corps d'expression lambda. Voir historique de révision pour le code original. Cela a l'avantage de rendre la définition un peu moins verbeuse; qui avait été l’un des principaux reproches concernant l’approche de cette réponse.

23
JohnLBevan

Si vous voulez obtenir un entier pour la valeur enum qui est stockée dans une variable, dont le type serait Question, à utiliser par exemple dans une méthode, vous pouvez simplement le faire, voici ce que j'ai écrit dans cet exemple:

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

Cela changera le titre de la fenêtre à 4 car la variable Geselecteerd est Talen.Nederlands. Si je le change en Talen.Portugees et que j'appelle à nouveau la méthode, le texte passera à 3.

J'ai eu du mal à trouver cette solution simple sur Internet et je ne pouvais pas la trouver, alors je testais quelque chose et je l'ai découvert. J'espère que cela t'aides. ;)

17

Pour vous assurer qu’une valeur enum existe, puis pour l’analyser, vous pouvez également procéder comme suit.

// 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() + ".");

J'espère que ça aide.

14
Nathon

Peut-être que je l'ai raté, mais quelqu'un a-t-il essayé une méthode d'extension générique simple. Cela fonctionne très bien pour moi. Vous pouvez éviter le transtypage dans votre API de cette manière, mais cela aboutit finalement à une opération de type de changement. C’est un bon exemple pour programmer Roselyn afin que le compilateur crée une méthode GetValue pour vous.

    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;
    }
}    
12
Doug
public enum QuestionType
{
    Role = 2,
    ProjectFunding = 3,
    TotalEmployee = 4,
    NumberOfServers = 5,
    TopBusinessConcern = 6
}

... est une belle déclaration.

Vous devez convertir le résultat en int comme ceci:

int Question = (int)QuestionType.Role

Sinon, le type est toujours QuestionType.

Ce niveau de rigueur correspond à la méthode C #.

Une alternative consiste à utiliser une déclaration de classe à la place:

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
}

C'est moins élégant à déclarer, mais vous n'avez pas besoin de le lancer dans le code:

int Question = QuestionType.Role

Vous pouvez également vous sentir plus à l'aise avec Visual Basic, qui répond à ce type d'attentes dans de nombreux domaines.

11

Une autre façon de le faire:

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

Aura pour résultat:

Name: Role, Value: 2
11
plavozont
int number = Question.Role.GetHashCode();

number devrait avoir la valeur 2.

9
JaimeArmenta

Vous pouvez le faire en implémentant une méthode d'extension dans votre type enum défini:

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

Ceci simplifie l'obtention de la valeur int de la valeur enum actuelle:

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

ou

int value = Question.Role.getNumberValue();
8
Bronek

Que diriez-vous d'une méthode d'extension à la place:

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

Et l'utilisation est légèrement plus jolie:

var intValue = Question.Role.IntValue();
7
SixOThree
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 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);
}
4
Gauravsa

Voici la méthode d'extension

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;
}
3
Kamran Shahid

Étant donné que les énumérations peuvent être déclarées avec plusieurs types primitifs, une méthode d'extension générique pour convertir tout type d'énumération peut être utile.

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;
3
Jeffrey Ferreiras

Mon fav hack avec int ou plus petits enums:

GetHashCode();

Pour un enum

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

cette

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

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

les sorties

one
1
1  
max
2147483647
2147483647    
min
-2147483648
-2147483648    

Disclaimer: Ne fonctionne pas pour les enums basés sur une longue

3
Erik Karlsson

L’exemple que je voudrais suggérer "pour obtenir la valeur" int "d’enum est,

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

int answer = (int)Sample.Book;

maintenant la réponse sera 1.

J'espère que cela pourrait aider quelqu'un.

2
Vivek

Essayez celui-ci au lieu de convertir enum en int:

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

La solution la plus simple à laquelle je puisse penser est de surcharger la méthode Get(int) comme ceci:

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

[modifiers] peut généralement être identique à celui de la méthode Get(int). Si vous ne pouvez pas éditer la classe Questions ou si, pour une raison quelconque, vous ne souhaitez pas le faire, vous pouvez surcharger la méthode en écrivant une extension:

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

Je suis un peu en retard pour le jeu mais je suis venu avec cette méthode d’extension qui inclut les fonctionnalités du langage courant. En utilisant dynamique, je n'ai pas besoin d'en faire une méthode générique et de spécifier le type qui maintient l'invocation plus simple et cohérente. S'il vous plaît laissez-moi savoir si j'ai fait quelque chose de mal:

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;
    }
1
Jeff

En Vb. CA devrait etre

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

Private value As Integer = CInt(Question.Role)
1
VPP
Question question = Question.Role;
int value = question.GetHashCode();

Entraînera value == 2.

Ceci n'est vrai que si l'enum correspond à l'intérieur d'un int

0
GinCanhViet