[c#] Ottieni un valore int da enum in C #



11 Answers

Poiché Enum può essere un qualsiasi tipo integrale ( byte , int , short , ecc.), Un modo più efficace per ottenere il valore integrale sottostante GetTypeCode 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.

Question

Ho una classe chiamata Questions (plurale). In questa classe c'è un enum chiamato Question (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 quello foo . C'è un modo semplice per ottenere il valore intero dall'enumerazione così posso fare qualcosa come Questions.Get(Question.Role) ?




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

... è una bella dichiarazione.

Devi trasmettere il risultato a int come:

int Question = (int)QuestionType.Role

Altrimenti, il tipo è ancora QuestionType .

Questo livello di rigore è il modo C #.

Un'alternativa è usare invece una dichiarazione di classe:

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
}

È meno elegante da dichiarare, ma non è necessario inserirlo nel codice:

int Question = QuestionType.Role

In alternativa, potresti sentirti più a tuo agio con Visual Basic, che soddisfa questo tipo di aspettativa in molte aree.




Forse l'ho perso ma qualcuno ha provato un semplice metodo di estensione generico. Questo funziona alla grande per me. È possibile evitare il cast del tipo nella propria API in questo modo, ma alla fine risulta un'operazione di tipo change. Questo è un buon caso per programmare Roselyn affinché il compilatore faccia un metodo GetValue per te.

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



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

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



Prova questo invece di convertire enum in int:

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



Recentemente mi sono convertito dall'usare le enumerazioni nel mio codice in favore di utilizzare invece classi con costruttori protetti e istanze statiche predefinite (grazie a Roelof - C # Garantire Valid Enum Values ​​- Futureproof Method ).

Alla luce di ciò, di seguito è come vorrei ora affrontare questo problema (compresa la conversione implicita in / da 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 ottieni tutto ciò che vorresti dall'enumerazione, ma il tuo codice ora è molto più flessibile, quindi se dovessi eseguire azioni diverse in base al valore di Question , puoi inserire la logica nella Question stessa (cioè nel modalità OO preferita) anziché mettere un sacco di istruzioni caso per tutto il codice per affrontare ogni scenario.

NB: rispondere aggiornato 2018-04-27 per utilizzare le funzionalità di C # 6; cioè espressioni di dichiarazione e definizioni del corpo di espressione lambda. Vedi la cronologia delle revisioni per il codice originale. Questo ha il vantaggio di rendere la definizione un po 'meno prolissa; che era stata una delle principali lamentele sull'approccio di questa risposta.




Se si desidera ottenere un numero intero per il valore enum memorizzato in una variabile, il cui tipo sarebbe Question , da utilizzare ad esempio in un metodo, è sufficiente eseguire ciò che 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 in 4 perché la variabile Geselecteerd è Talen.Nederlands . Se lo cambio a Talen.Portugees e chiamo di nuovo il metodo, il testo cambierà in 3.

Ho avuto difficoltà a trovare questa semplice soluzione su Internet e non ho potuto trovarla, quindi stavo testando qualcosa e ho trovato questo. Spero che questo ti aiuti. ;)




Prova questo :

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



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)



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

Risulterà in value == 2 .




My fav hack con int o enum più piccoli:

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    

Disclaimer: non funziona per enumerazioni basate su long




int number = Question.Role.GetHashCode();

number dovrebbe avere il valore 2 .




Related