[c#] Obtenga el valor int de enum en C #


Answers

Dado que Enums puede ser de cualquier tipo integral ( byte , int , short , etc.), una forma más sólida de obtener el valor integral subyacente de la enumeración sería hacer uso del método GetTypeCode junto con la clase Convert :

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

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

Esto debería funcionar independientemente del tipo integral subyacente.

Question

Tengo una clase llamada Questions (plural). En esta clase hay una enumeración llamada Question (singular) que se ve así.

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

En la clase de Questions , tengo una función get(int foo) que devuelve un objeto de Questions para ese foo . ¿Hay una manera fácil de obtener el valor entero de la enumeración para que pueda hacer algo como Questions.Get(Question.Role) ?




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

... es una buena declaración.

Tienes que lanzar el resultado a int así:

int Question = (int)QuestionType.Role

De lo contrario, el tipo sigue siendo QuestionType .

Este nivel de rigor es la forma C #.

Una alternativa es usar una declaración de clase en su lugar:

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
}

Es menos elegante para declarar, pero no es necesario que lo moldee en código:

int Question = QuestionType.Role

Alternativamente, puede sentirse más cómodo con Visual Basic, que atiende este tipo de expectativas en muchas áreas.




En Vb. Debería ser

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

Private value As Integer = CInt(Question.Role)



Prueba esto :

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



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

Dará como resultado un value == 2 .




Si desea obtener un número entero para el valor enum que está almacenado en una variable, cuyo tipo sería Question , para usar, por ejemplo, en un método, puede simplemente hacer esto. Escribí en este ejemplo:

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

Esto cambiará el título de la ventana a 4 porque la variable Geselecteerd es Talen.Nederlands . Si lo cambio a Talen.Portugees y Talen.Portugees llamar al método, el texto cambiará a 3.

Me costó encontrar esta solución simple en Internet y no pude encontrarla, así que estaba probando algo y descubrí esto. Espero que esto ayude. ;)




Recientemente, he evitado el uso de enumeraciones en mi código a favor de utilizar clases con constructores protegidos e instancias estáticas predefinidas (gracias a Roelof - C # Asegurar valores de entrada válidos - Método Futureproof ).

A la luz de esto, a continuación se explica cómo abordaría este problema (incluida la conversión implícita a / desde 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)
}

La ventaja de este enfoque es que obtienes todo lo que obtendrías de la enumeración, pero ahora tu código es mucho más flexible, así que si necesitas realizar diferentes acciones basadas en el valor de Question , puedes poner la lógica en la propia Question (es decir, en preferencia de OO moda) en lugar de poner un montón de declaraciones de casos a lo largo de su código para hacer frente a cada escenario.

NB: Respuesta actualizada 2018-04-27 para hacer uso de las características C # 6; es decir, expresiones de declaración y definiciones corporales de expresiones lambda. Ver el historial de revisiones para el código original. Esto tiene el beneficio de hacer que la definición sea un poco menos detallada; que ha sido una de las principales quejas sobre el enfoque de esta respuesta.




Mi hack favorito con enums int o más pequeños:

GetHashCode();

Por una enumeración

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

esta

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

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

salidas

one
1
1  
max
2147483647
2147483647    
min
-2147483648
-2147483648    

Descargo de responsabilidad: no funciona para enumeraciones basadas en long




Quizás me lo perdí, pero alguien ha intentado con un método de extensión genérico simple. Esto funciona genial para mí Puede evitar el tipo de conversión en su API de esta manera, pero finalmente da como resultado una operación de tipo de cambio. Este es un buen caso para programar a Roselyn para que el compilador haga un método de GetValue para usted.

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



Pruebe esto en lugar de convertir 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;        
}



Es más fácil de lo que piensas, una enumeración ya es una int. Solo necesita ser recordado:

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



int number = Question.Role.GetHashCode();

number debe tener el valor 2 .




Links