enums convert - Trasmetti int enum in C#




to integer (18)

Come si può lanciare un int a un enum in C #?


Answers

Sto usando questo pezzo di codice per trasmettere int al mio enum:

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

La trovo la soluzione migliore.


Un po 'di distanza dalla domanda originale, ma ho trovato una risposta alla domanda Ottieni un valore int da enum utile. Crea una classe statica con public const int proprietà public const int , che ti consentono di raccogliere facilmente un gruppo di costanti int correlate e di non doverle int a int quando le utilizzi.

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

Ovviamente, alcune delle funzionalità di tipo enum andranno perse, ma per la memorizzazione di una serie di costanti ID del database, sembra una soluzione piuttosto ordinata.


Non so più dove ottengo la parte di questa estensione enum, ma è da . Mi dispiace per questo! Ma ho preso questo e l'ho modificato per enumerare con Flags. Per enumerare con le bandiere, ho fatto questo:

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

Esempio:

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

A volte hai un oggetto al tipo MyEnum . Piace

var MyEnumType = typeof(MyEnumType);

Poi:

Enum.ToObject(typeof(MyEnum), 3)

Diversi modi di lanciare da e verso 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);


 }
}

Da una stringa:

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.")

Da un int:

YourEnum foo = (YourEnum)yourInt;

Aggiornare:

Dal numero puoi anche

YourEnum foo = (YourEnum)Enum.ToObject(typeof(YourEnum) , yourInt);

Per convertire una stringa in ENUM o int in costante ENUM, è necessario utilizzare la funzione Enum.Parse. Ecco un video di YouTube https://www.youtube.com/watch?v=4nhx4VwdRDk che in realtà dimostra con una stringa e lo stesso vale per int.

Il codice funziona come mostrato di seguito dove "rosso" è la stringa e "MyColors" è il colore ENUM che ha le costanti di colore.

MyColors EnumColors = (MyColors)Enum.Parse(typeof(MyColors), "Red");

Questo analizza interi o stringhe a un enum di destinazione con corrispondenza parziale in dot.NET 4.0 usando generici come nella classe di utilità di Tawani sopra. Lo sto usando per convertire variabili di switch da riga di comando che potrebbero essere incomplete. Poiché un enum non può essere nullo, è necessario fornire logicamente un valore predefinito. Può essere chiamato così:

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

Ecco il codice:

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

A proposito: la domanda riguardava i numeri interi, che nessuno menzionava anche in modo esplicito in Enum.TryParse ()


Di seguito è riportata una buona classe di utilità per 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;
    }
}

Basta lanciarlo:

MyEnum e = (MyEnum)3;

È possibile verificare se è nell'intervallo utilizzando Enum.IsDefined . È Enum.IsDefined :

if (Enum.IsDefined(typeof(MyEnum), 3)) { ... }

In alternativa, usa un metodo di estensione invece di una linea singola:

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

Uso:

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

O

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

Può aiutarti a convertire qualsiasi dato di input nell'enum desiderato dall'utente. Supponiamo di avere una enumerazione come di seguito che per impostazione predefinita int . Aggiungi un valore predefinito all'inizio del tuo enum. Che viene utilizzato dagli assistenti se non è stata trovata alcuna corrispondenza con il valore di input.

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: Qui cerco di analizzare il valore in int, perché enum è di default int Se si definisce enum come questo che è il tipo di byte .

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

È necessario modificare l'analisi dal metodo di supporto da

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

a

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

Controllo il mio metodo per i seguenti input

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

mi scusi per il mio inglese


Di seguito è un metodo di estensione leggermente migliore

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

Se si dispone di un numero intero che funge da maschera di bit e potrebbe rappresentare uno o più valori in un'enumerazione [Flags], è possibile utilizzare questo codice per analizzare i singoli valori di flag in un elenco:

for (var flagIterator = 0x1; flagIterator <= 0x80000000; flagIterator <<= 1)
{
    // Check to see if the current flag exists in the bit mask
    if ((intValue & flagIterator) != 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), flagIterator))
            ListOfEnumValues.Add((MyEnum)flagIterator);
    }
}

Prendi il seguente esempio:

int one = 1;
MyEnum e = (MyEnum)one;

Questo è un metodo di conversione sicura consapevole dell'enumerazione dei flag:

public static bool TryConvertToEnum<T>(this int instance, out T result)
  where T: struct
{
  var enumType = typeof (T);
  if (!enumType.IsEnum)
  {
    throw new ArgumentException("The generic type must be an enum.");
  }
  var success = Enum.IsDefined(enumType, instance);
  if (success)
  {
    result = (T)Enum.ToObject(enumType, instance);
  }
  else
  {
    result = default(T);
  }
  return success;
}

Nel mio caso, avevo bisogno di restituire l'enum da un servizio WCF. Avevo anche bisogno di un nome descrittivo, non solo di enum.ToString ().

Ecco la mia classe 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;
    }
}

Ecco il metodo di estensione che ottiene la descrizione dall'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();
        }
    }

Implementazione:

return EnumMember.ConvertToList<YourType>();

Voglio completare la risposta dei poligenelubrificanti:

Personalmente preferisco gli uguali (). Ma fa il controllo di compatibilità di tipo. Quale penso sia una limitazione importante.

Per verificare la compatibilità dei tipi al momento della compilazione, dichiarare e utilizzare una funzione personalizzata nell'enumerazione.

public boolean isEquals(enumVariable) // compare constant from left
public static boolean areEqual(enumVariable, enumVariable2) // compare two variable

Con questo, hai ottenuto tutti i vantaggi di entrambe le soluzioni: protezione NPE, codice di facile lettura e verifica della compatibilità del tipo in fase di compilazione.

Raccomando anche di aggiungere un valore UNDEFINED per enum.







c# enums casting