Question

J'ai une classe appelée Questions (au pluriel). Dans cette classe, il y a un Question appelé ENUM (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 retourne un objet Questions pour cette foo. Est-il un moyen facile d'obtenir la valeur entière de l'ENUM pour que je puisse faire quelque chose comme Questions.Get(Question.Role)?

Était-ce utile?

La solution

Il suffit de lancer le ENUM, par exemple.

int something = (int) Question.Role;

Le ci-dessus fonctionnera pour la grande majorité des énumérations que vous voyez dans la nature, comme la valeur par défaut type sous-jacent pour un ENUM est int.

Cependant, comme le souligne cecilphillip sur, les énumérations peuvent avoir différents types sous-jacents. Si une ENUM est déclarée comme uint, long ou ulong, il doit être jeté au type de ENUM; par exemple. pour

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

vous devez utiliser

long something = (long)StarsInMilkyWay.Wolf424B;

Autres conseils

Depuis énumérations peut être tout type intégral (byte, int, short, etc.), d'une manière plus robuste pour obtenir la valeur intégrale sous-jacente de l'ENUM serait d'utiliser la méthode de GetTypeCode conjointement 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.

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

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

Entraînera value == 2.

Sur le même sujet, si vous voulez obtenir la valeur de int de System.Enum, puis 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 simplement laid. Je préfère la première.

Il est plus facile que vous le pensez - un ENUM est déjà un int. Il a juste besoin d'être rappelé:

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

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

énumérations seront incrémenter par 1, et vous pouvez définir la valeur de départ. Si vous ne définissez pas la valeur de départ, il sera attribué à 0 au départ.

J'ai récemment converti loin d'utiliser énumérations dans mon code en faveur de la place en utilisant des classes avec des constructeurs et des instances protégées statiques prédéfinies (grâce à Roelof - C # assurer que les valeurs valides Enum -. FutureProof méthode )

À la lumière de cela, ci-dessous est la façon dont j'aborde maintenant cette question (y compris la conversion implicite / de 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 du ENUM, mais votre code est maintenant beaucoup plus souple, donc si vous avez besoin d'effectuer différentes actions en fonction de la valeur de Question, vous pouvez mettre logique dans Question lui-même ( à-dire à la mode OO préféré) par opposition à mettre beaucoup de déclarations de cas dans votre code pour aborder chaque scénario.


NB: Réponse mise à jour 27/04/2018 à utiliser 6 C # caractéristiques; à savoir les expressions de déclaration et de définitions de corps d'expression lambda. Voir l'historique de révision pour le code d'origine. Cela a l'avantage de rendre la définition un peu moins bavard; qui avait été l'une des principales plaintes au sujet de l'approche de cette réponse.

Si vous voulez obtenir un entier pour la valeur ENUM qui est stockée dans une variable, wich type serait Question, à utiliser par exemple dans une méthode, vous pouvez simplement faire ceci je l'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 va changer le titre de la fenêtre à 4 car la variable Geselecteerd est Talen.Nederlands. Si je change à Talen.Portugees et appeler à nouveau la méthode, le texte passe à 3.

J'ai eu du mal à trouver cette solution simple sur internet et je ne pouvais pas trouver, donc je testais quelque chose et trouvé cela. J'espère que cela t'aides. ;)

Pour assurer une valeur ENUM existe et l'analyser, vous pouvez aussi faire ce qui 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 cette aide.

Peut-être que je l'ai raté, mais a quelqu'un a essayé une méthode simple d'extension générique. Cela fonctionne très bien pour moi. Vous pouvez éviter la distribution de type dans votre API de cette façon, mais en fin de compte, il se traduit par une opération de type de modification. Ceci est un bon cas pour la programmation Roselyn pour avoir le compilateur faire 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;
    }
}    

Une autre façon de le faire:

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

Entraînera:

Name: Role, Value: 2
public enum QuestionType
{
    Role = 2,
    ProjectFunding = 3,
    TotalEmployee = 4,
    NumberOfServers = 5,
    TopBusinessConcern = 6
}

... est une déclaration bien.

Vous ne devez jeter le résultat int comme ceci:

int Question = (int)QuestionType.Role

Dans le cas contraire, le type est toujours QuestionType.

Ce niveau de rigueur est la voie C #.

Une alternative consiste à utiliser une déclaration de classe au lieu:

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égante de déclarer, mais vous n'avez pas besoin de le jeter dans le code:

int Question = QuestionType.Role

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

Vous pouvez le faire en mettant en place un Méthode d'extension à votre type enum défini:

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

Cette valeur Simplify obtenir int de la valeur actuelle ENUM:

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

ou

int value = Question.Role.getNumberValue();
int number = Question.Role.GetHashCode();

number doit avoir la valeur 2.

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

Mon fav tranchent énumérations int ou moins:

GetHashCode();

Pour un ENUM

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

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

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

sorties

one
1
1  
max
2147483647
2147483647    
min
-2147483648
-2147483648    

Disclaimer: Ne fonctionne pas pour les énumérations basée sur une longue

ci-après le procédé 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;
}

Depuis énumérations peuvent être déclarés avec plusieurs types primitifs, une méthode d'extension générique pour associer tout type de ENUM 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;

L'exemple que je voudrais suggérer « pour obtenir « int » valeur de 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.

La solution la plus simple que je peux penser sature la méthode Get(int) comme ceci:

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

[modifiers] peut généralement être le même que pour la méthode de Get(int). Si vous ne pouvez pas modifier la classe Questions ou pour une raison quelconque ne voulez pas, 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);
    }
}

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

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

Dans Vb. Il devrait être

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

Private value As Integer = CInt(Question.Role)

Je un peu tard pour le jeu, mais je suis venu avec cette méthode d'extension qui inclut des fonctionnalités linguistiques actuelles. En utilisant dynamique, je ne ai pas besoin d'en faire une méthode générique et préciser le type qui maintient l'invocation plus simple et cohérente. S'il vous plaît laissez-moi savoir si je l'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;
    }
Question question = Question.Role;
int value = question.GetHashCode();

Entraînera value == 2.

  

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

Essayez ceci:

int value = YourEnum.ToString("D");
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top