Como converter int para enum?

3193

Como pode intser convertido para um enumem c #?

lomaxx
fonte

Respostas:

3794

De uma sequência:

YourEnum foo = (YourEnum) Enum.Parse(typeof(YourEnum), yourString);

// The foo.ToString().Contains(",") check is necessary for enumerations marked with an [Flags] attribute
if (!Enum.IsDefined(typeof(YourEnum), foo) && !foo.ToString().Contains(","))
{
    throw new InvalidOperationException($"{yourString} is not an underlying value of the YourEnum enumeration.")
}

De um int:

YourEnum foo = (YourEnum)yourInt;

Atualizar:

Do número, você também pode

YourEnum foo = (YourEnum)Enum.ToObject(typeof(YourEnum) , yourInt);
FlySwat
fonte
31
@FlySwat, e se YourEnumfor dinâmico e só for conhecido em tempo de execução, e o que eu quero é converter Enum?
Shimmy Weitzhandler
226
Esteja ciente de que o Enum.Parse NÃO funcionará se o seu código for ofuscado. No tempo de execução após a ofuscação, a string é comparada aos nomes de enumerações e, nesse ponto, os nomes das enumerações não são o que você esperaria que fossem. Sua análise falhará onde eles tiveram sucesso antes como resultado.
Jropella # 26/13
158
CUIDADO Se você usar a sintaxe "de uma string" acima e passar uma string inválida que é um número (por exemplo, "2342342" - assumindo que esse valor não seja o valor da sua enumeração), ele permitirá isso sem gerar nenhum erro! Sua enumeração terá esse valor (2342342), mesmo que não seja uma opção válida na enumeração em si.
JoeCool
132
Eu acho que essa resposta está um pouco datada agora. Para string, você realmente deve estar usando var result = Enum.TryParse(yourString, out yourEnum)hoje em dia (e verificando o resultado para determinar se a conversão falhou).
Justin T Conroy
20
Também é possível fazer Enum.ParsetrueYourEnum foo = (YourEnum) Enum.Parse(typeof(YourEnum), yourString, true);
distinção
900

Basta transmitir:

MyEnum e = (MyEnum)3;

Você pode verificar se está dentro do alcance usando Enum.IsDefined :

if (Enum.IsDefined(typeof(MyEnum), 3)) { ... }
Matt Hamilton
fonte
218
Cuidado para não usar Enum.IsDefined se você usar o atributo Flags e o valor for uma combinação de sinalizadores, por exemplo: Keys.L | Keys.Control
dtroy 31/07/2009
15
Em relação a Enum.IsDefined, lembre-se de que isso pode ser perigoso: msdn.microsoft.com/en-us/library/ms229025(VS.90).aspx
adrian
3
Prefiro esta definição: "Retorna uma indicação se existe uma constante com um valor especificado em uma enumeração especificada" do MSDN
Pap
3
... Porque a sua definição pode ser enganosa, porque você está dizendo: "... verificar se é na faixa ..." o que implica dentro de um intervalo de números com início e fim limites ...
Pap
3
@ mac9416 Tentei dar um exemplo sucinto em gist.github.com/alowdon/f7354cda97bac70b44e1c04bc0991bcc - basicamente, usando IsDefinedpara verificar os valores de entrada, você se deixa vulnerável a pessoas que adicionam novos valores de enum posteriormente, o que passaria em uma IsDefinedverificação (uma vez que o novo existe no novo código), mas que pode não funcionar com o código original que você escreveu. Portanto, é mais seguro especificar explicitamente os valores de enumeração que seu código pode manipular.
adrian
238

Como alternativa, use um método de extensão em vez de uma linha:

public static T ToEnum<T>(this string enumString)
{
    return (T) Enum.Parse(typeof (T), enumString);
}

Uso:

Color colorEnum = "Red".ToEnum<Color>();

OU

string color = "Red";
var colorEnum = color.ToEnum<Color>();
Abdul Munim
fonte
7
Para processar a entrada do usuário, provavelmente é uma boa idéia chamar a sobrecarga do Enum.Parse que permite especificar que a comparação NÃO diferencia maiúsculas de minúsculas (ou seja, um usuário digitando "vermelho" (minúsculo) travaria o código acima sem essa alteração .)
BrainSlugs83
9
Útil, mas a pergunta é específica sobre ints.
BJury
2
isso também funciona se a string é um número inteiro, por exemplo, "2"
TruthOf42
2
Isso gerará uma exceção se enumString for nulo (teve um problema semelhante ontem). Considere usar o TryParse em vez do Parse. O TryParse também verificará se T é do tipo Enum
Justin
Esse tipo de método de extensão System.Stringparece poluir o espaço para nome #
Anderson Anderson
160

Penso que para obter uma resposta completa, as pessoas precisam saber como as enums funcionam internamente no .NET.

Como as coisas funcionam

Uma enumeração no .NET é uma estrutura que mapeia um conjunto de valores (campos) para um tipo básico (o padrão é int). No entanto, você pode realmente escolher o tipo integral para o qual sua enum mapeia:

public enum Foo : short

Nesse caso, a enumeração é mapeada para o shorttipo de dados, o que significa que será armazenado na memória como um curto e se comportará como um curto quando você o converter e usar.

Se você olhar para ele do ponto de vista da IL, um enum (normal, int) será assim:

.class public auto ansi serializable sealed BarFlag extends System.Enum
{
    .custom instance void System.FlagsAttribute::.ctor()
    .custom instance void ComVisibleAttribute::.ctor(bool) = { bool(true) }

    .field public static literal valuetype BarFlag AllFlags = int32(0x3fff)
    .field public static literal valuetype BarFlag Foo1 = int32(1)
    .field public static literal valuetype BarFlag Foo2 = int32(0x2000)

    // and so on for all flags or enum values

    .field public specialname rtspecialname int32 value__
}

O que deve chamar sua atenção aqui é que o value__arquivo é armazenado separadamente dos valores da enumeração. No caso da enum Fooacima, o tipo de value__é int16. Isso basicamente significa que você pode armazenar o que quiser em uma enumeração, desde que os tipos correspondam .

Neste ponto, gostaria de salientar que System.Enumé um tipo de valor, o que basicamente significa que BarFlagocupará 4 bytes na memória e Fooocupará 2 - por exemplo, o tamanho do tipo subjacente (na verdade é mais complicado que isso, mas Ei...).

A resposta

Portanto, se você tem um número inteiro que deseja mapear para uma enumeração, o tempo de execução precisa fazer apenas duas coisas: copiar os 4 bytes e nomeá-la de outra forma (o nome da enumeração). A cópia está implícita porque os dados são armazenados como tipo de valor - isso basicamente significa que, se você usar código não gerenciado, poderá simplesmente trocar enumerações e números inteiros sem copiar dados.

Para torná-lo seguro, acho que é uma prática recomendada saber que os tipos subjacentes são iguais ou implicitamente conversíveis e garantir que os valores da enumeração existam (eles não são verificados por padrão!).

Para ver como isso funciona, tente o seguinte código:

public enum MyEnum : int
{
    Foo = 1,
    Bar = 2,
    Mek = 5
}

static void Main(string[] args)
{
    var e1 = (MyEnum)5;
    var e2 = (MyEnum)6;

    Console.WriteLine("{0} {1}", e1, e2);
    Console.ReadLine();
}

Observe que a conversão para e2também funciona! Da perspectiva do compilador acima, isso faz sentido: o value__campo é simplesmente preenchido com 5 ou 6 e, quando Console.WriteLinechamadas ToString(), o nome de e1é resolvido enquanto o nome de e2não é.

Se não foi isso que você pretendia, use Enum.IsDefined(typeof(MyEnum), 6)para verificar se o valor que você está convertendo é mapeado para uma enumeração definida.

Observe também que sou explícito sobre o tipo subjacente da enum, mesmo que o compilador realmente verifique isso. Estou fazendo isso para garantir que não tenha surpresas no caminho. Para ver essas surpresas em ação, você pode usar o seguinte código (na verdade, eu já vi isso acontecer muito no código do banco de dados):

public enum MyEnum : short
{
    Mek = 5
}

static void Main(string[] args)
{
    var e1 = (MyEnum)32769; // will not compile, out of bounds for a short

    object o = 5;
    var e2 = (MyEnum)o;     // will throw at runtime, because o is of type int

    Console.WriteLine("{0} {1}", e1, e2);
    Console.ReadLine();
}
atlaste
fonte
7
Sei que este é um post antigo, mas como você obtém esse nível de conhecimento em c #? Isso é lido através da especificação C #?
Rolan
20
@Rolan Às vezes, desejo que mais pessoas perguntem isso. :-) Para ser sincero, eu realmente não sei; Tento entender como as coisas funcionam e obter informações sempre que possível. Eu li o padrão C #, mas também descompilei regularmente o código com o Reflector (eu até olho muito o código do assembler x86) e faço várias pequenas experiências. Além disso, conhecer outros idiomas ajuda nesse caso; Eu pratico CS há cerca de 30 anos e, em algum momento, certas coisas se tornam "lógicas" - f.ex. uma enumeração deve ser de tipos integrais, porque, caso contrário, a interoperabilidade será interrompida (ou seu desempenho será prejudicado).
Atlaste
9
Acredito que a chave para fazer a engenharia de software corretamente é saber como as coisas funcionam. Para mim, isso significa que, se você escrever um pedaço de código, sabe como ele se traduz aproximadamente em f.ex. operações do processador e busca / gravação de memória. Se você perguntar como chegar a esse nível, sugiro construir vários casos de teste pequenos, tornando-os mais difíceis à medida que avança, tente prever o resultado todas as vezes e testá-lo depois (incluindo descompilação, etc.). Depois de descobrir todos os detalhes e todas as características, você pode verificar se acertou no padrão (sem graça). Pelo menos, essa seria a minha abordagem.
Atlaste
1
Resposta fantástica, obrigado! No seu último exemplo de código, ele lança uma exceção no tempo de execução porque o é um objeto. Você pode converter uma variável int em um curto, desde que caia dentro do curto intervalo.
gravidThoughts
@gravidThoughts Obrigado. Na verdade, é uma operação de unboxing, por isso não fará conversões implícitas como as que você descreve. Às vezes, a transmissão é confusa em C #, se você não conhece os detalhes ... De qualquer forma, porque int! = short, Será lançada (a remoção do unboxing falha). Se você o fizer object o = (short)5;, funcionará, porque os tipos corresponderão. Não é sobre o alcance, é realmente sobre o tipo.
Atlaste 12/08/16
121

Veja o seguinte exemplo:

int one = 1;
MyEnum e = (MyEnum)one;
abigblackman
fonte
64

Estou usando este pedaço de código para converter int para minha enumeração:

if (typeof(YourEnum).IsEnumDefined(valueToCast)) return (YourEnum)valueToCast;
else { //handle it here, if its not defined }

Acho a melhor solução.

MSkuta
fonte
1
isso é bom. Fiquei surpreso que não há uma exceção ao converter um valor inválido para uma enumeração int-suportada.
Orion elenzil
Na verdade, isso não é tão diferente da resposta mais bem avaliada. Essa resposta também discute o uso de Enum.IsDefined após a conversão da string para o tipo Enum. Assim, mesmo se a cadeia foi escalado sem erro, Enum.IsDefined ainda vai pegá-lo
Don Cheadle
53

Abaixo está uma boa classe de utilitário para Enums

public static class EnumHelper
{
    public static int[] ToIntArray<T>(T[] value)
    {
        int[] result = new int[value.Length];
        for (int i = 0; i < value.Length; i++)
            result[i] = Convert.ToInt32(value[i]);
        return result;
    }

    public static T[] FromIntArray<T>(int[] value) 
    {
        T[] result = new T[value.Length];
        for (int i = 0; i < value.Length; i++)
            result[i] = (T)Enum.ToObject(typeof(T),value[i]);
        return result;
    }


    internal static T Parse<T>(string value, T defaultValue)
    {
        if (Enum.IsDefined(typeof(T), value))
            return (T) Enum.Parse(typeof (T), value);

        int num;
        if(int.TryParse(value,out num))
        {
            if (Enum.IsDefined(typeof(T), num))
                return (T)Enum.ToObject(typeof(T), num);
        }

        return defaultValue;
    }
}
Tawani
fonte
47

Para valores numéricos, isso é mais seguro, pois retornará um objeto, não importa o que:

public static class EnumEx
{
    static public bool TryConvert<T>(int value, out T result)
    {
        result = default(T);
        bool success = Enum.IsDefined(typeof(T), value);
        if (success)
        {
            result = (T)Enum.ToObject(typeof(T), value);
        }
        return success;
    }
}
Sébastien Duval
fonte
Não funciona para enum de sinalizadores
Seyed Morteza Mousavi
44

Se você estiver pronto para o 4.0 .NET Framework, há uma nova função Enum.TryParse () que é muito útil e funciona bem com o atributo [Flags]. Consulte o método Enum.TryParse (String, TEnum%)

Ryan Russon
fonte
21
Isso é útil ao converter de uma string. Mas não ao converter de um int.
CodesInChaos
35

Se você tiver um número inteiro que atue como uma máscara de bits e possa representar um ou mais valores em uma enumeração [Flags], poderá usar esse código para analisar os valores de sinalizadores individuais em uma lista:

for (var flagIterator = 0; flagIterator < 32; flagIterator++)
{
    // Determine the bit value (1,2,4,...,Int32.MinValue)
    int bitValue = 1 << flagIterator;

    // Check to see if the current flag exists in the bit mask
    if ((intValue & bitValue) != 0)
    {
        // If the current flag exists in the enumeration, then we can add that value to the list
        // if the enumeration has that flag defined
        if (Enum.IsDefined(typeof(MyEnum), bitValue))
            Console.WriteLine((MyEnum)bitValue);
    }
}

Observe que isso pressupõe que o tipo subjacente do enumé um número inteiro de 32 bits assinado. Se fosse um tipo numérico diferente, você teria que alterar os 32 codificados permanentemente para refletir os bits desse tipo (ou derivá-lo programaticamente usando Enum.GetUnderlyingType())

Evan M
fonte
1
Esse loop nunca termina? flagIterator = 0x00000001, flagIterator = 0x00000002, flagIterator = 0x00000004, ..., flagIterator = 0x40000000, flagIterator = 0x80000000, flagIterator = 0x00000000. Em outras palavras, o valor sempre será menor que 0x80000000 porque ele excederá zero após o caso em que o bit D31 = 1. Então, ele permanecerá 0 para sempre porque, ao sair da esquerda, o valor 0 fornece 0
Christian Gingras
Grande captura @christiangingras, obrigado! Eu tenho modificado a resposta para a conta para isso, e deve ter em conta quando o mais alto bit é definido (ou seja 0x80000000 / Int32.MinValue)
Evan M
27

Às vezes você tem um objeto para o MyEnumtipo. Gostar

var MyEnumType = typeof(MyEnumType);

Então:

Enum.ToObject(typeof(MyEnum), 3)
LD
fonte
26

Este é um método de conversão segura com reconhecimento de enumeração de sinalizadores:

public static bool TryConvertToEnum<T>(this int instance, out T result)
  where T: Enum
{
  var enumType = typeof (T);
  var success = Enum.IsDefined(enumType, instance);
  if (success)
  {
    result = (T)Enum.ToObject(enumType, instance);
  }
  else
  {
    result = default(T);
  }
  return success;
}
Daniel Fisher lennybacon
fonte
3
Agora, isso pode ser aprimorado com o C # 7.3, restringindo-o a, e Enumnão struct, o que significa que não precisamos confiar na verificação do tempo de execução!
Scott
20

insira a descrição da imagem aqui

Para converter uma string em constante ENUM ou int em ENUM, precisamos usar a função Enum.Parse. Aqui está um vídeo do youtube https://www.youtube.com/watch?v=4nhx4VwdRDk que realmente demonstra com string e o mesmo se aplica a int.

O código segue como mostrado abaixo, onde "vermelho" é a sequência e "MyColors" é a cor ENUM que possui constantes de cores.

MyColors EnumColors = (MyColors)Enum.Parse(typeof(MyColors), "Red");
Shivprasad Koirala
fonte
20

Afastando-me um pouco da pergunta original, mas encontrei uma resposta para a pergunta Stack Overflow Obter valor int de enum útil. Crie uma classe estática com public const intpropriedades, permitindo que você colete facilmente um monte de intconstantes relacionadas e depois não precise convertê-las ao intusá-las.

public static class Question
{
    public static readonly int Role = 2;
    public static readonly int ProjectFunding = 3;
    public static readonly int TotalEmployee = 4;
    public static readonly int NumberOfServers = 5;
    public static readonly int TopBusinessConcern = 6;
}

Obviamente, algumas das funcionalidades do tipo enum serão perdidas, mas, para armazenar um monte de constantes de identificação de banco de dados, parece uma solução bem organizada.

Ted
fonte
5
enums substituiu o uso de constantes inteiras assim desde que eles fornecem mais segurança de tipo
Paul Richards
1
Paul, este é um método de coletar constantes int relacionadas (por exemplo, constantes de ID do banco de dados), para que possam ser usadas diretamente sem precisar convertê-las para int toda vez que forem usadas. O tipo deles é inteiro, não por exemplo, DatabaseIdsEnum.
Ted
1
Eu encontrei pelo menos uma situação em que a segurança do tipo enum pode ser ignorada sem querer.
Thierry
Mas enums também certificar-se os valores são únicos, algo esta abordagem também está faltando
derHugo
15

Isso analisa números inteiros ou seqüências de caracteres em uma enumeração de destino com correspondência parcial no dot.NET 4.0 usando genéricos como na classe de utilitário de Tawani acima. Estou usando-o para converter variáveis ​​de opção da linha de comando que podem estar incompletas. Como uma enum não pode ser nula, você deve fornecer logicamente um valor padrão. Pode ser chamado assim:

var result = EnumParser<MyEnum>.Parse(valueToParse, MyEnum.FirstValue);

Aqui está o código:

using System;

public class EnumParser<T> where T : struct
{
    public static T Parse(int toParse, T defaultVal)
    {
        return Parse(toParse + "", defaultVal);
    }
    public static T Parse(string toParse, T defaultVal) 
    {
        T enumVal = defaultVal;
        if (defaultVal is Enum && !String.IsNullOrEmpty(toParse))
        {
            int index;
            if (int.TryParse(toParse, out index))
            {
                Enum.TryParse(index + "", out enumVal);
            }
            else
            {
                if (!Enum.TryParse<T>(toParse + "", true, out enumVal))
                {
                    MatchPartialName(toParse, ref enumVal);
                }
            }
        }
        return enumVal;
    }

    public static void MatchPartialName(string toParse, ref T enumVal)
    {
        foreach (string member in enumVal.GetType().GetEnumNames())
        {
            if (member.ToLower().Contains(toParse.ToLower()))
            {
                if (Enum.TryParse<T>(member + "", out enumVal))
                {
                    break;
                }
            }
        }
    }
}

FYI: A pergunta era sobre números inteiros, que ninguém mencionado também converterá explicitamente em Enum.TryParse ()

CZahrobsky
fonte
13

Em uma sequência: (Enum.Parse está desatualizado, use Enum.TryParse)

enum Importance
{}

Importance importance;

if (Enum.TryParse(value, out importance))
{
}
Will Yu
fonte
4
A pergunta pergunta especificamente sobre números inteiros.
BJury
4
Will Yu Edite a sua resposta para que todos saibam Enum.TryParse vai trabalhar em uma corda do valor ou o nome do enum (não pude resistir)
JeremyWeir
1
Jeremy, Weir trabalhando nisso (também não resisti).
precisa saber é o seguinte
11

A seguir é um método de extensão ligeiramente melhor

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;
        }
Kamran Shahid
fonte
10

No meu caso, eu precisava retornar a enumeração de um serviço WCF. Eu também precisava de um nome amigável, não apenas o enum.ToString ().

Aqui está minha classe do WCF.

[DataContract]
public class EnumMember
{
    [DataMember]
    public string Description { get; set; }

    [DataMember]
    public int Value { get; set; }

    public static List<EnumMember> ConvertToList<T>()
    {
        Type type = typeof(T);

        if (!type.IsEnum)
        {
            throw new ArgumentException("T must be of type enumeration.");
        }

        var members = new List<EnumMember>();

        foreach (string item in System.Enum.GetNames(type))
        {
            var enumType = System.Enum.Parse(type, item);

            members.Add(
                new EnumMember() { Description = enumType.GetDescriptionValue(), Value = ((IConvertible)enumType).ToInt32(null) });
        }

        return members;
    }
}

Aqui está o método Extension que obtém a Descrição do Enum.

    public static string GetDescriptionValue<T>(this T source)
    {
        FieldInfo fileInfo = source.GetType().GetField(source.ToString());
        DescriptionAttribute[] attributes = (DescriptionAttribute[])fileInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);            

        if (attributes != null && attributes.Length > 0)
        {
            return attributes[0].Description;
        }
        else
        {
            return source.ToString();
        }
    }

Implementação:

return EnumMember.ConvertToList<YourType>();
LawMan
fonte
9

Eu não sei mais de onde eu recebo a parte dessa extensão enum, mas é do stackoverflow. Desculpe-me por isto! Mas peguei este e modifiquei-o para enumerações com Flags. Para enums com Flags, fiz o seguinte:

  public static class Enum<T> where T : struct
  {
     private static readonly IEnumerable<T> All = Enum.GetValues(typeof (T)).Cast<T>();
     private static readonly Dictionary<int, T> Values = All.ToDictionary(k => Convert.ToInt32(k));

     public static T? CastOrNull(int value)
     {
        T foundValue;
        if (Values.TryGetValue(value, out foundValue))
        {
           return foundValue;
        }

        // For enums with Flags-Attribut.
        try
        {
           bool isFlag = typeof(T).GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0;
           if (isFlag)
           {
              int existingIntValue = 0;

              foreach (T t in Enum.GetValues(typeof(T)))
              {
                 if ((value & Convert.ToInt32(t)) > 0)
                 {
                    existingIntValue |= Convert.ToInt32(t);
                 }
              }
              if (existingIntValue == 0)
              {
                 return null;
              }

              return (T)(Enum.Parse(typeof(T), existingIntValue.ToString(), true));
           }
        }
        catch (Exception)
        {
           return null;
        }
        return null;
     }
  }

Exemplo:

[Flags]
public enum PetType
{
  None = 0, Dog = 1, Cat = 2, Fish = 4, Bird = 8, Reptile = 16, Other = 32
};

integer values 
1=Dog;
13= Dog | Fish | Bird;
96= Other;
128= Null;
Franki1986
fonte
9

Você deve criar algum tipo de relaxamento correspondente para ser mais robusto.

public static T ToEnum<T>(dynamic value)
{
    if (value == null)
    {
        // default value of an enum is the object that corresponds to
        // the default value of its underlying type
        // https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/default-values-table
        value = Activator.CreateInstance(Enum.GetUnderlyingType(typeof(T)));
    }
    else if (value is string name)
    {
        return (T)Enum.Parse(typeof(T), name);
    }

    return (T)Enum.ToObject(typeof(T),
             Convert.ChangeType(value, Enum.GetUnderlyingType(typeof(T))));
}

Caso de teste

[Flags]
public enum A : uint
{
    None  = 0, 
    X     = 1 < 0,
    Y     = 1 < 1
}

static void Main(string[] args)
{
    var value = EnumHelper.ToEnum<A>(7m);
    var x = value.HasFlag(A.X); // true
    var y = value.HasFlag(A.Y); // true

    var value2 = EnumHelper.ToEnum<A>("X");

    var value3 = EnumHelper.ToEnum<A>(null);

    Console.ReadKey();
}

fonte
Esta é uma boa resposta. É uma pena que esteja tão abaixo da página no momento!
MikeBeaton 20/02
8

Diferentes maneiras de transmitir de e para Enum

enum orientation : byte
{
 north = 1,
 south = 2,
 east = 3,
 west = 4
}

class Program
{
  static void Main(string[] args)
  {
    orientation myDirection = orientation.north;
    Console.WriteLine(“myDirection = {0}”, myDirection); //output myDirection =north
    Console.WriteLine((byte)myDirection); //output 1

    string strDir = Convert.ToString(myDirection);
        Console.WriteLine(strDir); //output north

    string myString = north”; //to convert string to Enum
    myDirection = (orientation)Enum.Parse(typeof(orientation),myString);


 }
}
usuário do gmail
fonte
8

Pode ajudá-lo a converter qualquer dado de entrada na enumeração desejada pelo usuário . Suponha que você tenha um enum como abaixo do qual, por padrão, int . Adicione um valor padrão no início da sua enumeração. Que é usado no método de ajuda quando não há correspondência encontrada com o valor de entrada.

public enum FriendType  
{
    Default,
    Audio,
    Video,
    Image
}

public static class EnumHelper<T>
{
    public static T ConvertToEnum(dynamic value)
    {
        var result = default(T);
        var tempType = 0;

        //see Note below
        if (value != null &&
            int.TryParse(value.ToString(), out  tempType) && 
            Enum.IsDefined(typeof(T), tempType))
        {
            result = (T)Enum.ToObject(typeof(T), tempType); 
        }
        return result;
    }
}

NB: Aqui eu tento analisar o valor em int, porque enum é por padrão int Se você definir enum como este, que é do tipo byte .

public enum MediaType : byte
{
    Default,
    Audio,
    Video,
    Image
} 

Você precisa alterar o método de análise no auxiliar de

int.TryParse(value.ToString(), out  tempType)

para

byte.TryParse(value.ToString(), out tempType)

Verifico meu método para as seguintes entradas

EnumHelper<FriendType>.ConvertToEnum(null);
EnumHelper<FriendType>.ConvertToEnum("");
EnumHelper<FriendType>.ConvertToEnum("-1");
EnumHelper<FriendType>.ConvertToEnum("6");
EnumHelper<FriendType>.ConvertToEnum("");
EnumHelper<FriendType>.ConvertToEnum("2");
EnumHelper<FriendType>.ConvertToEnum(-1);
EnumHelper<FriendType>.ConvertToEnum(0);
EnumHelper<FriendType>.ConvertToEnum(1);
EnumHelper<FriendType>.ConvertToEnum(9);

Desculpe pelo meu Inglês

reza.cse08
fonte
8

Aqui está um método de extensão que lança Int32a Enum.

Ele honra sinalizadores bit a bit, mesmo quando o valor é maior que o máximo possível. Por exemplo, se você tiver um enum com as possibilidades 1 , 2 e 4 , mas o int for 9 , ele entenderá como 1 na ausência de um 8 . Isso permite que você faça atualizações de dados antes das atualizações de código.

   public static TEnum ToEnum<TEnum>(this int val) where TEnum : struct, IComparable, IFormattable, IConvertible
    {
        if (!typeof(TEnum).IsEnum)
        {
            return default(TEnum);
        }

        if (Enum.IsDefined(typeof(TEnum), val))
        {//if a straightforward single value, return that
            return (TEnum)Enum.ToObject(typeof(TEnum), val);
        }

        var candidates = Enum
            .GetValues(typeof(TEnum))
            .Cast<int>()
            .ToList();

        var isBitwise = candidates
            .Select((n, i) => {
                if (i < 2) return n == 0 || n == 1;
                return n / 2 == candidates[i - 1];
            })
            .All(y => y);

        var maxPossible = candidates.Sum();

        if (
            Enum.TryParse(val.ToString(), out TEnum asEnum)
            && (val <= maxPossible || !isBitwise)
        ){//if it can be parsed as a bitwise enum with multiple flags,
          //or is not bitwise, return the result of TryParse
            return asEnum;
        }

        //If the value is higher than all possible combinations,
        //remove the high imaginary values not accounted for in the enum
        var excess = Enumerable
            .Range(0, 32)
            .Select(n => (int)Math.Pow(2, n))
            .Where(n => n <= val && n > 0 && !candidates.Contains(n))
            .Sum();

        return Enum.TryParse((val - excess).ToString(), out asEnum) ? asEnum : default(TEnum);
    }
Chad Hedgcock
fonte
6

a maneira fácil e clara de converter um int enum em c #:

 public class Program
    {
        public enum Color : int
        {
            Blue = 0,
            Black = 1,
            Green = 2,
            Gray = 3,
            Yellow =4
        }

        public static void Main(string[] args)
        {
            //from string
            Console.WriteLine((Color) Enum.Parse(typeof(Color), "Green"));

            //from int
            Console.WriteLine((Color)2);

            //From number you can also
            Console.WriteLine((Color)Enum.ToObject(typeof(Color) ,2));
        }
    }
Mohammad Aziz Nabizada
fonte
6

Você simplesmente usa a conversão explícita Cast int para enum ou enum para int

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine((int)Number.three); //Output=3

        Console.WriteLine((Number)3);// Outout three
        Console.Read();
    }

    public enum Number
    {
        Zero = 0,
        One = 1,
        Two = 2,
        three = 3
    }
}
Shivam Mishra
fonte
4
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace SamplePrograme
{
    public class Program
    {
        public enum Suit : int
        {
            Spades = 0,
            Hearts = 1,
            Clubs = 2,
            Diamonds = 3
        }

        public static void Main(string[] args)
        {
            //from string
            Console.WriteLine((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));
        }
    }
}
Aswal
fonte
3

Você apenas faz como abaixo:

int intToCast = 1;
TargetEnum f = (TargetEnum) intToCast ;

Para se certificar de que você apenas lança os valores corretos e pode gerar uma exceção caso contrário:

int intToCast = 1;
if (Enum.IsDefined(typeof(TargetEnum), intToCast ))
{
    TargetEnum target = (TargetEnum)intToCast ;
}
else
{
   // Throw your exception.
}

Observe que o uso de IsDefined é caro e ainda mais do que apenas a conversão, portanto, depende da sua implementação decidir usá-lo ou não.

Mselmi Ali
fonte
3

Você pode usar o método de extensão.

public static class Extensions
{

    public static T ToEnum<T>(this string data) where T : struct
    {
        if (!Enum.TryParse(data, true, out T enumVariable))
        {
            if (Enum.IsDefined(typeof(T), enumVariable))
            {
                return enumVariable;
            }
        }

        return default;
    }

    public static T ToEnum<T>(this int data) where T : struct
    {
        return (T)Enum.ToObject(typeof(T), data);
    }
}

use como código abaixo

enum:

public enum DaysOfWeeks
{
    Monday = 1,
    Tuesday = 2,
    Wednesday = 3,
    Thursday = 4,
    Friday = 5,
    Saturday = 6,
    Sunday = 7,
}

Uso:

 string Monday = "Mon";
 int Wednesday = 3;
 var Mon = Monday.ToEnum<DaysOfWeeks>();
 var Wed = Wednesday.ToEnum<DaysOfWeeks>();
Reza Jenabi
fonte