enums string - Obtenir la valeur int de enum en C#




class custom (21)

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


Answers

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

Une autre façon de le faire:

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

Aura pour résultat:

Name: Role, Value: 2

Peut-être que je l'ai manqué, mais quelqu'un a essayé une méthode d'extension générique simple. Cela fonctionne très bien pour moi. Vous pouvez éviter le type cast dans votre API de cette façon, mais finalement, il en résulte une opération de type changement. C'est un bon cas pour programmer Roselyn pour que le compilateur fasse 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;
    }
}    

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

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:

int Question = (int)QuestionType.Role

Sinon, le type est toujours QuestionType .

Ce niveau de rigueur est le moyen 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
}

Il est moins élégant de déclarer, mais vous n'avez pas besoin de le convertir en code:

int Question = QuestionType.Role

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


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

Va entraîner la value == 2 .


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


Exemple:

Public Enum EmpNo
{
    Raj = 1
    Rahul,
    Priyanka
}

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

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

ou

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

Les énumérations seront incrémentées de 1 et vous pourrez définir la valeur de départ. Sinon, il sera affecté initialement à 0.


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

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.


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

int number = Question.Role.GetHashCode();

number devrait avoir la valeur 2 .


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.


Essaye ça :

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

Puisque les énumérations peuvent être déclarées avec plusieurs types de primitives, une méthode d'extension générique pour lancer n'importe quel 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;

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

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)

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.


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.


Sur une note connexe, si vous voulez obtenir la valeur int de System.Enum , alors donné 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 carrément laids. Je préfère le premier.


J'ai essayé d'améliorer le code un peu:

public T LoadEnum<T>(string value, T defaultValue = default(T)) where T : struct, IComparable, IFormattable, IConvertible
{
    if (Enum.IsDefined(typeof(T), value))
    {
        return (T)Enum.Parse(typeof(T), value, true);
    }
    return defaultValue;
}






c# enums casting int