Pregunta

Tengo una clase llamada Questions (plural). En esta clase no es una enumeración llamada Question (singular) que se parece a esto.

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

En la clase Questions, que tienen una función get(int foo) que devuelve un objeto Questions para que 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)?

¿Fue útil?

Solución

Sólo tire la enumeración, por ejemplo.

int something = (int) Question.Role;

Lo anterior va a trabajar para la gran mayoría de las enumeraciones que se ve en la naturaleza, como el tipo subyacente por defecto para una enumeración es int.

Sin embargo, como cecilphillip señala, enumeraciones pueden tener diferentes tipos subyacentes. Si una enumeración se declara como un uint, long o ulong, se debe convertir al tipo de la enumeración; p.ej. para

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

debería utilizar

long something = (long)StarsInMilkyWay.Wolf424B;

Otros consejos

Desde Enums puede ser cualquier tipo integral (byte, int, short, etc.), una forma más sólida para obtener el valor integral subyacente de la enumeración sería hacer uso del método de GetTypeCode en conjunción 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.

Declarar como una clase estática que tienen constantes públicos:

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

Y a continuación, puede hacer referencia a ella como Question.Role, y siempre se evalúa como un int o lo que se define como.

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

también se value == 2.

En una nota relacionada, si se quiere obtener el valor de int System.Enum, e continuación se da aquí:

Enum e = Question.Role;

Puede utilizar:

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

Los dos últimos son feo llano. Yo prefiero la primera.

Es más fácil de lo que piensa - una enumeración ya es un int. Sólo necesita que se le recuerde:

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

Ejemplo:

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

Y en el código subyacente para obtener valor de enumeración:

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

o

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

Las enumeraciones se incrementará en 1, y se puede establecer el valor inicial. Si no se establece el valor inicial se le asignará como 0 inicialmente.

Me he convertido recientemente lejos de usar las enumeraciones en mi código a favor de las clases en lugar de utilizar con constructores protegidos o las instancias estáticas predefinidas (gracias a Roelof - C # asegurar valores de enumeración válidos -. FutureProof método )

En vista de ello, a continuación es como Ahora me acerco a este tema (incluyendo 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 se consigue todo lo que tendría con la enumeración, pero su código es ahora mucho más flexible, por lo que si usted necesita para llevar a cabo diferentes acciones en función del valor de Question, puede poner la lógica en Question sí mismo ( es decir, en la forma preferida OO) en comparación con poner un montón de declaraciones de casos en todo el código para hacer frente a cada escenario.


Nota: Respuesta actualiza 04/27/2018 a hacer uso de C # 6 funciones; es decir, expresiones de declaración y definiciones cuerpo de expresión lambda. Ver historia de revisiones de código original. Esto tiene la ventaja de hacer la definición un poco menos prolijo; que había sido una de las principales quejas sobre el enfoque de esta respuesta.

Si desea obtener un entero para el valor de enumeración que se almacena en una variable, cosa que el tipo sería Question, para utilizar, por ejemplo, en un método, puede simplemente hacer esto que 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 Geselecteerd variable es Talen.Nederlands. Si lo cambio a Talen.Portugees y llame al método nuevo, el texto cambiará a 3.

Yo tenía un tiempo difícil encontrar esta solución simple en el Internet y no pude encontrarlo, así que estaba probando algo y descubrí esto. Espero que esto ayude. ;)

Para garantizar la existencia de un valor de enumeración y luego analizarlo, también puede hacer lo siguiente.

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

Espero que esto ayude.

Tal vez no me di cuenta, pero ¿alguien ha intentado un método simple extensión genérica. Esto funciona muy bien para mí. Usted puede evitar el tipo de molde en su API de esta manera, pero en última instancia se traduce en una operación de tipo de cambio. Este es un buen ejemplo para la programación Roselyn tener el compilador crea un método 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;
    }
}    

Una forma más de hacerlo:

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

se traducirá en:

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

... es una buena declaración.

Usted tiene que emitir el resultado a int, así:

int Question = (int)QuestionType.Role

De lo contrario, el tipo es todavía QuestionType.

Este nivel de rigurosidad es la forma en C #.

Una alternativa es utilizar 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 para su emisión en código:

int Question = QuestionType.Role

Como alternativa, se puede sentir más cómodo con Visual Basic, que atiende a este tipo de expectativa en muchas áreas.

Usted puede hacer esto mediante la implementación de un Método de extensión para su tipo de enumeración definido:

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

Esta simplificar conseguir int valor del valor de enumeración actual:

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

o

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

number debe tener el valor 2.

¿Qué tal un método de extensión en su lugar:

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

Y el uso es ligeramente más bonita:

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

Mi favorito piratear con int o menores enumeraciones:

GetHashCode();

Para una enumeración

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

salidas

one
1
1  
max
2147483647
2147483647    
min
-2147483648
-2147483648    

Renuncia: No funciona para las enumeraciones en base a largo

A continuación se presenta el método de extensión

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

Desde enumeraciones se pueden declarar con múltiples tipos primitivos, un método de extensión genérico para lanzar cualquier tipo de enumeración puede ser útil.

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;

El ejemplo me gustaría sugerir 'para obtener 'int' valor de enumeración es,'

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

int answer = (int)Sample.Book;

Ahora la respuesta será 1.

Espero que esto podría ayudar a alguien.

La solución más fácil que se me ocurre es la sobrecarga del método Get(int) como esto:

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

donde [modifiers] generalmente puede ser el mismo que para el método Get(int). Si no se puede editar la clase Questions o por alguna razón no desea, puede sobrecargar el método escribiendo una extensión:

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

Prueba esta enumeración en lugar de convertir a int:

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

En Vb. Debe ser

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

Private value As Integer = CInt(Question.Role)

Yo un poco tarde para el juego, pero se me ocurrió con este método de extensión que incluye las características del lenguaje corriente. Mediante el uso dinámico, que no necesito para hacer de este un método genérico y especificar el tipo que mantiene la invocación simple y consistente. Por favor, hágamelo saber si he hecho algo 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();

también se value == 2.

  

Esto sólo es cierto si la enumeración se ajusta dentro de un int

Prueba esto:

int value = YourEnum.ToString("D");
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top