sintaxis - obtener el valor numerico de un enum c#
Obtener valor int de enumeraciĆ³n en C# (25)
¿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 un poco más bonito:
var intValue = Question.Role.IntValue();
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 Questions
, tengo una función get(int foo)
que devuelve un objeto 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)
?
A continuación se muestra 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;
}
Acaba de lanzar la enumeración, por ejemplo
int something = (int) Question.Role;
Lo anterior funcionará para la gran mayoría de las enumeraciones que se ven en la naturaleza, ya que el tipo subyacente predeterminado para una enumeración es int
.
Sin embargo, como señala cecilphillip , las enumeraciones pueden tener diferentes tipos subyacentes. Si una enumeración se declara como una uint
, long
o ulong
, se debe convertir al tipo de enumeración; por ejemplo para
enum StarsInMilkyWay:long {Sun = 1, V645Centauri = 2 .. Wolf424B = 2147483649};
Deberías usar
long something = (long)StarsInMilkyWay.Wolf424B;
Como las enumeraciones pueden declararse con varios tipos primitivos, puede ser útil un método de extensión genérico para emitir cualquier tipo de enumeración.
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;
Como las enumeraciones pueden 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 utilizar el 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 de integral subyacente.
Declara como una clase estática que tiene constantes públicas:
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 luego puede hacer referencia a él como Question.Role
, y siempre se evalúa como un int
o como se lo define.
Ejemplo:
Public Enum EmpNo
{
Raj = 1
Rahul,
Priyanka
}
Y en el código de atrás para obtener el valor 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 aumentarán en 1, y puede establecer el valor de inicio. De lo contrario se asignará como 0 inicialmente.
El ejemplo que me gustaría sugerir ''para obtener el valor'' int ''de enum es''
public enum Sample
{Book =1, Pen=2, Pencil =3}
int answer = (int)Sample.Book;
Ahora la respuesta será 1.
Espero que esto pueda ayudar a alguien.
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)
En una nota relacionada, si desea obtener el valor int
de System.Enum
, entonces System.Enum
aquí:
Enum e = Question.Role;
Puedes usar:
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 simplemente feos. Prefiero la primera.
Es más fácil de lo que piensas: una enumeración ya es un int. Solo necesita ser recordado:
int y = (int)Question.Role;
Console.WriteLine(y); // prints 2
La solución más fácil que se me ocurre es sobrecargar el método Get(int)
siguiente manera:
[modifiers] Questions Get(Question q)
{
return Get((int)q);
}
donde [modifiers]
generalmente pueden ser los mismos que para el método Get(int)
. Si no puede editar la clase Questions
o, por algún motivo, no desea hacerlo, 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);
}
}
Mi truco favorito con int o enums más pequeños:
GetHashCode();
Para 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 largas
Para asegurarse de que exista 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.
Prueba esto :
int value = YourEnum.ToString("D");
Pruebe este 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;
}
Puede hacer esto implementando un método de extensión a su tipo de enumeración definido:
public static class MyExtensions
{
public static int getNumberValue(this Question questionThis)
{
return (int)questionThis;
}
}
Esto simplifica la obtención del valor int del valor de enumeración actual:
Question question = Question.Role;
int value = question.getNumberValue();
o
int value = Question.Role.getNumberValue();
Recientemente he dejado de usar enumeraciones en mi código en lugar de usar clases con constructores protegidos e instancias estáticas predefinidas (gracias a Roelof - C # Garantice valores válidos de enumeración - Método a prueba de futuro ).
A la luz de eso, a continuación se muestra cómo abordaré 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 obtiene todo lo que tendría de la enumeración, pero su código ahora es mucho más flexible, por lo que si necesita realizar diferentes acciones basadas en el valor de la Question
, puede poner la lógica en la Question
misma (es decir, en el moda OO preferida) en lugar de poner muchas declaraciones de casos en todo el código para abordar cada escenario.
NB: respuesta actualizada 2018-04-27 para hacer uso de las características de C # 6; Es decir, expresiones de declaración y definiciones de cuerpo de expresión lambda. Vea el historial de revisiones para el código original. Esto tiene la ventaja de hacer la definición un poco menos detallada; que había sido una de las principales quejas sobre el enfoque de esta respuesta.
Si desea obtener un número entero para el valor de enumeración que se almacena en una variable, cuyo tipo sería Question
, para usar por ejemplo en un método, simplemente puede 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 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ó mucho encontrar esta solución simple en Internet y no pude encontrarla, así que estaba probando algo y descubrí esto. Espero que esto ayude. ;)
Tal vez me lo perdí, pero alguien ha probado un método de extensión genérico simple. Esto funciona muy bien para mí. Puede evitar el tipo de conversión en su API de esta manera, pero en última instancia, resulta en una operación de tipo de cambio. Este es un buen caso para programar a Roselyn para que el compilador realice 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);
Resultará en:
Name: Role, Value: 2
Question question = Question.Role;
int value = (int) question;
Resultará en value == 2
.
int number = Question.Role.GetHashCode();
number
debe tener el valor 2
.
public enum QuestionType
{
Role = 2,
ProjectFunding = 3,
TotalEmployee = 4,
NumberOfServers = 5,
TopBusinessConcern = 6
}
... es una buena declaración.
Tienes que lanzar el resultado para que sea así:
int Question = (int)QuestionType.Role
De lo contrario, el tipo sigue siendo QuestionType
.
Este nivel de rigor es el camino 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 declararlo, pero no es necesario que lo emita en código:
int Question = QuestionType.Role
Alternativamente, puede sentirse más cómodo con Visual Basic, que satisface este tipo de expectativas en muchas áreas.
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);
}