with - Obter valor int de enum em c#




what is enum c# (17)

Eu tenho uma classe chamada Questions (plural). Nesta classe há um enum chamado Question (singular) que se parece com isso.

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

Na classe Questions , tenho uma função get(int foo) que retorna um objeto Questions para esse foo . Existe uma maneira fácil de obter o valor inteiro do enum para que eu possa fazer algo como Questions.Get(Question.Role) ?


É mais fácil do que você pensa - um enum já é um int. Só precisa ser lembrado:

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

A seguir está o método de extensão

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

Apenas elenco o enum, por exemplo

int something = (int) Question.Role;

As opções acima funcionarão para a grande maioria das enums que você vê na natureza, já que o tipo subjacente padrão para um enum é int .

No entanto, como aponta o cecilphillip , os enums podem ter diferentes tipos subjacentes. Se um enum for declarado como uint , long ou ulong , ele deverá ser convertido para o tipo do enum; por exemplo para

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

você deveria usar

long something = (long)StarsInMilkyWay.Wolf424B;

Como Enums pode ser qualquer tipo integral ( byte , int , short , etc.), uma maneira mais robusta de obter o valor integral subjacente do enum seria fazer uso do método GetTypeCode em conjunto com a classe Convert :

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

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

Isso deve funcionar independentemente do tipo integral subjacente.


Como sobre um método de extensão:

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

E o uso é um pouco mais bonito:

var intValue = Question.Role.IntValue();

Declare-o como uma classe estática com 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;
}

E então você pode referenciá-lo como Question.Role , e ele sempre avalia para um int ou o que você define como.


Em uma nota relacionada, se você quiser obter o valor int de System.Enum , então, dê e aqui:

Enum e = Question.Role;

Você pode 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);

Os dois últimos são feios. Eu prefiro o primeiro.


Eu recentemente converti longe de usar enums no meu código em vez de usar classes com construtores protegidos e instâncias estáticas predefinidas (graças ao Roelof - C # Assegure Valores Enum Válidos - Método Futureproof ).

À luz disso, abaixo está como eu agora abordaria esse problema (incluindo a conversão implícita de / para 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)
}

A vantagem desta abordagem é que você obtém tudo o que você teria do enum, mas seu código agora é muito mais flexível, então se você precisar executar ações diferentes com base no valor de Question , você pode colocar a lógica em Question self (ie no a moda OO preferida) ao invés de colocar muitas declarações de caso em todo o seu código para lidar com cada cenário.

NB: Resposta atualizada 2018-04-27 para fazer uso de recursos do C # 6; ou seja, expressões de declaração e definições de corpo de expressão lambda. Veja o histórico de revisões do código original. Isso tem o benefício de tornar a definição um pouco menos detalhada; que tinha sido uma das principais queixas sobre a abordagem desta resposta.


Mais uma maneira de fazer isso:

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

Vai resultar em:

Name: Role, Value: 2

Meu fav hackear com int ou enums menores:

GetHashCode();

Para um enum

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

isto

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

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

saídas

one
1
1  
max
2147483647
2147483647    
min
-2147483648
-2147483648    

Isenção de responsabilidade: não funciona para enums com base em longa


Para garantir que um valor enum exista e, em seguida, analise-o, você também pode fazer o seguinte.

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

Eu espero que isso ajude.


Se você deseja obter um inteiro para o valor enum que é armazenado em uma variável, que o tipo seria Question , para usar, por exemplo, em um método, você pode simplesmente fazer isso, escrevi neste exemplo:

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

Isto irá mudar o título da janela para 4 porque a variável Talen.Nederlands é Talen.Nederlands . Se eu mudar para Talen.Portugees e chamar o método novamente, o texto mudará para 3.

Eu tive dificuldade em encontrar essa solução simples na internet e não consegui encontrá-la, então estava testando algo e descobri isso. Espero que isto ajude. ;)


Tente este em vez de converter enum para int:

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

Tente isto:

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

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

... é uma boa declaração.

Você tem que converter o resultado para int assim:

int Question = (int)QuestionType.Role

Caso contrário, o tipo ainda é QuestionType .

Este nível de rigor é o caminho C #.

Uma alternativa é usar uma declaração de 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
}

É menos elegante declarar, mas você não precisa converter o código:

int Question = QuestionType.Role

Como alternativa, você pode se sentir mais confortável com o Visual Basic, que atende a esse tipo de expectativa em muitas á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);
}

int number = Question.Role.GetHashCode();

number deve ter o valor 2 .







int