Domanda

Ho una classe denominata Questions (plurale). In questa classe c'è una chiamata Question enum (singolare), che assomiglia a questo.

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

Nella classe Questions, ho una funzione get(int foo) che restituisce un oggetto Questions per quella foo. C'è un modo semplice per ottenere il valore intero da enum modo che io possa fare qualcosa di simile Questions.Get(Question.Role)?

È stato utile?

Soluzione

Basta lanciare l'enum, per es.

int something = (int) Question.Role;

È possibile che questo funzionerà per la stragrande maggioranza delle enumerazioni che si vede in natura, come il tipo sottostante di default per un enum è int.

Tuttavia, come cecilphillip sottolinea, enumerazioni possono avere diversi tipi sottostanti. Se un enum è dichiarata come uint, long o ulong, dovrebbe essere gettato al tipo di enum; per esempio. per

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

si dovrebbe usare

long something = (long)StarsInMilkyWay.Wolf424B;

Altri suggerimenti

Da Enums può essere qualsiasi tipo integrale (byte, int, short, ecc), un modo più robusto per ottenere il valore integrale sottostante dell'enumerazione sarebbe quello di utilizzare il metodo GetTypeCode in combinazione con la classe Convert:

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

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

Questo dovrebbe funzionare indipendentemente dal tipo integrale sottostante.

dichiara come una classe statica con costanti pubblici:

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

E poi si può fare riferimento come Question.Role, e restituisce sempre un int o qualsiasi altra cosa si definisce come.

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

Si tradurrà in value == 2.

In una nota correlata, se si vuole ottenere il valore int da System.Enum, poi dato e qui:

Enum e = Question.Role;

È possibile utilizzare:

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

Gli ultimi due sono semplicemente brutto. Io preferisco il primo.

E 'più facile di quanto si pensi - un enum è già un int. Ha solo bisogno di essere ricordato:

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

Esempio:

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

E nel codice dietro per ottenere il valore enum:

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

o

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

enumerazioni si incrementerà di 1, ed è possibile impostare il valore iniziale. Se non si imposta il valore iniziale sarà assegnato come 0 inizialmente.

Ho recentemente convertito lontano da utilizzando le enumerazioni nel mio codice a favore di invece di usare classi con costruttori protette e le istanze statiche predefiniti (grazie a Roelof - C # garantire validi valori enum -. FutureProof metodo )

Alla luce di questo, al di sotto è come mi piacerebbe ora affrontare la questione (compresa la conversione implicita da / per 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)
}

Il vantaggio di questo approccio è che si ottiene tutto quello che si avrebbe da enum, ma il codice è ora molto più flessibile, in modo da dovrebbe è necessario eseguire diverse azioni in base al valore di Question, si può mettere la logica in Question stesso ( vale a dire nel campo della moda OO preferita) al contrario di mettere un sacco di istruzioni case in tutto il codice per affrontare ogni scenario.


NB: Risposta aggiornato 2018/04/27 a fare uso di C # 6 caratteristiche; cioè espressioni dichiarazione e definizioni espressione lambda corpo. Vedere cronologia delle revisioni per codice originale. Questo ha il vantaggio di rendere la definizione un po 'meno prolissa; che era stato uno dei principali lamentele circa l'approccio di questa risposta.

Se si desidera ottenere un numero intero per il valore enum che viene memorizzato in una variabile, wich il tipo sarebbe Question, da utilizzare ad esempio in un metodo, si può semplicemente fare questo ho scritto in questo esempio:

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

Questo cambierà il titolo della finestra a 4 perché il Geselecteerd variabile è Talen.Nederlands. Se lo cambio a Talen.Portugees e chiamare il metodo di nuovo, il testo cambierà 3.

ho avuto difficoltà a trovare questa semplice soluzione su internet e non sono riuscito a trovarlo, così stavo testando qualcosa e ho trovato questo fuori. Spero che sia di aiuto. ;)

Per assicurare esiste un valore di enumerazione e poi analizzarlo, è possibile anche effettuare le seguenti operazioni.

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

Spero che questo aiuta.

Forse ho perso, ma qualcuno ha provato un semplice metodo di estensione generico. Questa grande opera per me. È possibile evitare il cast tipo nel vostro API questo modo, ma in ultima analisi, si traduce in un'operazione tipo di modifica. Questo è un buon esempio per la programmazione Roselyn di avere il compilatore fanno un metodo GetValue per voi.

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

Un altro modo per farlo:

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

Si tradurrà in:

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

... è una bella dichiarazione.

Si ha per lanciare il risultato da int in questo modo:

int Question = (int)QuestionType.Role

In caso contrario, il tipo è ancora QuestionType.

Questo livello di severità è il C # modo.

Un'alternativa è quella di utilizzare una dichiarazione di classe, invece:

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
}

E 'meno elegante di dichiarare, ma non c'è bisogno di lanciare nel codice:

int Question = QuestionType.Role

In alternativa, si può sentire più a suo agio con Visual Basic che si rivolge per questo tipo di aspettativa in molti settori.

È possibile farlo mediante l'attuazione di un Metodo di estensione per il tipo enum definito:

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

Questa semplificare ottenere valore int di valore enum corrente:

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

o

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

number dovrebbe avere il valore di 2.

Come su un metodo di estensione, invece:

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

E l'utilizzo è leggermente più bella:

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

La mia preferita incidere con int o più piccoli enumerazioni:

GetHashCode();

Per un enum

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

questo

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

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

uscite

one
1
1  
max
2147483647
2147483647    
min
-2147483648
-2147483648    

Avviso: Non funziona per le enumerazioni in base a lungo

In seguito è il metodo di estensione

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

Dato che le enumerazioni possono essere dichiarati con più tipi primitivi, un metodo di estensione generica per lanciare qualsiasi tipo enum può essere 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'esempio vorrei suggerire 'per ottenere 'int' valore da enum è,'

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

int answer = (int)Sample.Book;

Ora la risposta sarà 1.

Spero che questo possa aiutare qualcuno.

La soluzione più semplice che posso pensare sta sovraccaricando il metodo Get(int) in questo modo:

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

dove [modifiers] può generalmente essere lo stesso per il metodo Get(int). Se non è possibile modificare la classe Questions o per qualche ragione non si desidera, è possibile sovraccaricare il metodo scrivendo un interno:

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

Prova questo, invece di convertire enum a int:

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

In Vb. Dovrebbe essere

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

Private value As Integer = CInt(Question.Role)

I un po 'tardi per il gioco, ma sono arrivato fino a questo metodo di estensione che include funzionalità del linguaggio corrente. Utilizzando dinamica, non ho bisogno di rendere questo un metodo generico e specificare il tipo che mantiene l'invocazione più semplice e coerente. Si prega di farmi sapere se ho fatto qualcosa che non va:

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

Si tradurrà in value == 2.

  

Questo è vero solo se l'enum si inserisce all'interno di un int

Prova questo:

int value = YourEnum.ToString("D");
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top