custom - Obtenir la valeur int de enum en C#




if enum c# (16)

C'est plus facile que vous ne le pensez - une énumération est déjà int. Il a juste besoin d'être rappelé:

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

J'ai une classe appelée Questions (pluriel). Dans cette classe il y a un enum appelé 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 ce foo . Y at-il un moyen facile d'obtenir la valeur entière de l'énumération afin que je puisse faire quelque chose comme Questions.Get(Question.Role) ?


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 puis vous pouvez le référencer comme Question.Role , et il évalue toujours à un int ou à tout ce que vous définissez comme.


Essaye ça :

int value = YourEnum.ToString("D");

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

Je me suis récemment éloigné de l'utilisation d'enums dans mon code pour utiliser à la place des classes avec des constructeurs protégés et des instances statiques prédéfinies (grâce à Roelof - C # Ensure Valid Enum Values ​​- Futureproof Method ).

À la lumière de cela, voici comment je vais aborder ce problème (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'énumération, mais votre code est maintenant beaucoup plus flexible, alors si vous devez effectuer différentes actions basées sur la valeur de Question , vous pouvez mettre la logique dans Question elle-même. mode OO préféré) plutôt que de mettre beaucoup de déclarations de cas à travers votre code pour s'attaquer à chaque scénario.

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


Juste jeter l'enum, par exemple

int something = (int) Question.Role;

Ce qui précède fonctionnera pour la grande majorité des énumérations que vous voyez dans la nature, car le type sous-jacent par défaut pour un enum est int .

Cependant, comme le souligne cecilphillip , les enums peuvent avoir différents types sous-jacents. Si une énumération est déclarée comme uint , long , ou ulong , elle devrait être convertie en le type de l'enum; par exemple pour

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

Tu devrais utiliser

long something = (long)StarsInMilkyWay.Wolf424B;

La solution la plus simple que 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 pour une raison quelconque, 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);
    }
}

Mon bidouillage de fav avec int enums ou plus petit:

GetHashCode();

Pour une énumération

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

ce

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 de longues


Pour vous assurer qu'une valeur enum existe et ensuite l'analyser, vous pouvez également effectuer les opérations suivantes.

// 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.


Puisque Enums peut être n'importe quel type intégral ( byte , int , short , etc.), une méthode plus robuste pour obtenir la valeur intégrale sous-jacente de l'enum serait d'utiliser la méthode GetTypeCode en conjonction avec 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.


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

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 faire ceci 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 parce que la variable Geselecteerd est Talen.Nederlands . Si je le change à Talen.Portugees et appelle à nouveau la méthode, le texte passera à 3.

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


Une autre façon de le faire:

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

Aura pour résultat:

Name: Role, Value: 2

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

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

Va entraîner la value == 2 .


int number = Question.Role.GetHashCode();

number devrait avoir la valeur 2 .







int