Cast int to enum in C#

Jak można wrzucić int do enum w C#?

Author: alexy13, 2008-08-27

21 answers

From a string:

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

From an int:

YourEnum foo = (YourEnum)yourInt;

Update:

Z numeru można również

YourEnum foo = (YourEnum)Enum.ToObject(typeof(YourEnum) , yourInt);
 3174
Author: FlySwat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-05 08:56:25

Just cast it:

MyEnum e = (MyEnum)3;

Możesz sprawdzić, czy jest w zasięgu używając Enum.Isdefiniowane :

if (Enum.IsDefined(typeof(MyEnum), 3)) { ... }
 736
Author: Matt Hamilton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-27 04:01:14

Alternatywnie, użyj metody przedłużania zamiast jednowierszowej:

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

użycie:

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

Lub

string color = "Red";
var colorEnum = color.ToEnum<Color>();
 203
Author: Abdul Munim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-07 20:07:50

Aby uzyskać pełną odpowiedź, ludzie muszą wiedzieć, jak enums działa wewnętrznie w .NET.]}

Jak to działa

Enum w. NET jest strukturą, która mapuje zbiór wartości (pól) na typ podstawowy (domyślnie jest to int). Jednak w rzeczywistości można wybrać typ całki, do którego mapuje się enum:
public enum Foo : short

W tym przypadku enum jest mapowane na typ danych short, co oznacza, że będzie przechowywane w pamięci jako short i będzie zachowywać się jak short, gdy rzucaj i używaj.

Jeśli spojrzeć na to z punktu widzenia IL, a (normal, int) enum wygląda tak:

.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__
}

Należy zwrócić uwagę na to, że value__ jest przechowywany oddzielnie od wartości enum. W przypadku enum Foo powyżej, typem value__ jest int16. Oznacza to, że możesz przechowywać wszystko, co chcesz w enum, tak długo, jak typy pasują .

W tym miejscu chciałbym zwrócić uwagę, że System.Enum jest typem wartości, który w zasadzie oznacza to, że BarFlag zajmie 4 bajty w pamięci, a Foo zajmie 2 - np. rozmiar bazowego typu (jest to bardziej skomplikowane, ale hej...).

Odpowiedź

Tak więc, jeśli masz liczbę całkowitą, którą chcesz zmapować do enum, runtime musi zrobić tylko 2 rzeczy: skopiować 4 bajty i nazwać je czymś innym(nazwa enum). Kopiowanie jest niejawne, ponieważ dane są przechowywane jako typ wartości - oznacza to zasadniczo, że jeśli używasz niezarządzanych kod, można po prostu wymieniać Liczby i liczby całkowite bez kopiowania danych.

Aby było to bezpieczne, myślę, że najlepszą praktyką jest wiedzieć, że typy bazowe są takie same lub domyślnie wymienialne i upewnić się, że wartości enum istnieją (nie są sprawdzane domyślnie!).

Aby zobaczyć jak to działa, wypróbuj następujący kod:

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

Zauważ, że casting do e2 również działa! Z powyższego punktu widzenia kompilatora ma to sens: pole value__ jest po prostu wypełnione z 5 lub 6 i gdy Console.WriteLine wywoła ToString(), nazwa e1 jest rozwiązywana, podczas gdy nazwa e2 nie jest.

Jeśli nie to zamierzałeś, użyj Enum.IsDefined(typeof(MyEnum), 6), aby sprawdzić, czy wartość, którą rzucasz mapami do zdefiniowanego enum.

Zauważ również, że jestem wyraźny co do podstawowego typu enum, mimo że kompilator faktycznie to sprawdza. Robię to, by upewnić się, że nie natknę się na żadne niespodzianki. Aby zobaczyć te niespodzianki w akcji, możesz użyć następującego kodu (w zasadzie widziałem to często w kodzie bazy danych):

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();
}
 121
Author: atlaste,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-03 07:39:44

Weźmy następujący przykład:

int one = 1;
MyEnum e = (MyEnum)one;
 92
Author: abigblackman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-25 09:39:23

Używam tego fragmentu kodu, aby wrzucić int do mojego enum:

if (typeof(YourEnum).IsEnumDefined(valueToCast)) return (YourEnum)valueToCast;
else { //handle it here, if its not defined }
Uważam to za najlepsze rozwiązanie.
 56
Author: MSkuta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-21 10:05:43

Poniżej jest ładna Klasa użytkowa dla Enum

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;
    }
}
 45
Author: Tawani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-07 04:42:51

Jeśli jesteś gotowy na Framework 4.0 . NET , JEST NOWY Enum.TryParse () funkcja, która jest bardzo przydatna i dobrze gra z atrybutem [Flags]. Zobacz Też Enum.Metoda TryParse 'A (String, TEnum%)

 37
Author: Ryan Russon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-31 20:33:02

Dla wartości liczbowych jest to bezpieczniejsze, ponieważ zwróci obiekt bez względu na wszystko:

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;
    }
}
 37
Author: Sébastien Duval,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-07 20:09:01

Jeśli masz liczbę całkowitą, która działa jako maska bitowa i może reprezentować jedną lub więcej wartości w wyliczeniu [Flags], możesz użyć tego kodu do przetworzenia poszczególnych wartości flag na listę:

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);
    }
}
 25
Author: Evan M,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-13 20:13:13

Czasami masz obiekt typu MyEnum. Jak

var MyEnumType = typeof(MyEnumType);

Wtedy:

Enum.ToObject(typeof(MyEnum), 3)
 22
Author: L. D.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-31 20:30:55

To jest flags enumeration aware safe convert method:

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;
}
 18
Author: Daniel Fisher lennybacon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-20 13:16:55

Tutaj wpisz opis obrazka

Aby skonwertować ciąg znaków na enum lub int na stałą ENUM musimy użyć Enum.Funkcja Parse. Oto film z youtube https://www.youtube.com/watch?v=4nhx4VwdRDk które faktycznie demonstrują ' s z string i to samo dotyczy int.

Kod idzie jak pokazano poniżej, gdzie " red "jest ciągiem znaków, a" MyColors " jest ENUM kolorów, które ma stałe kolorów.

MyColors EnumColors = (MyColors)Enum.Parse(typeof(MyColors), "Red");
 17
Author: Shivprasad Koirala,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-05 12:15:25

Nieco oddalając się od pierwotnego pytania, ale znalazłem odpowiedź na pytanie Stack Overflow Get int value from enum przydatne. Utwórz statyczną klasę z właściwościami public const int, pozwalając na łatwe zebranie razem kilku powiązanych stałych int, a następnie nie musisz ich wyrzucać do int podczas ich używania.

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

Oczywiście część funkcji typu enum zostanie utracona, ale w przypadku przechowywania kilku stałych id bazy danych wydaje się to dość uporządkowane rozwiązanie.

 14
Author: Ted,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:39

To parsuje liczby całkowite lub ciągi znaków do docelowego enum z częściowym dopasowaniem w dot.NET 4.0 przy użyciu leków generycznych, jak w powyższej klasie użyteczności Tawani. Używam go do konwersji zmiennych przełącznika wiersza poleceń, które mogą być niekompletne. Ponieważ enum nie może być null, należy logicznie podać wartość domyślną. Można go nazwać tak:

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

Oto kod:

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: pytanie dotyczyło liczb całkowitych, o których nikt nie wspomniał, będą też jawnie konwertować w Enum.TryParse ()

 10
Author: CZahrobsky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-30 22:16:59

From a string: (Enum.Parse jest nieaktualne, użyj Enum.TryParse)

enum Importance
{}

Importance importance;

if (Enum.TryParse(value, out importance))
{
}
 10
Author: Will Yu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-21 00:32:24

Poniżej znajduje się nieco lepsza metoda rozszerzenia

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;
        }
 8
Author: Kamran Shahid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-06 10:22:38

W moim przypadku musiałem zwrócić enum z usługi WCF. Potrzebowałem też przyjaznej nazwy, nie tylko enum.ToString().

To moja klasa 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;
    }
}

Oto metoda rozszerzenia, która pobiera Opis Z 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();
        }
    }

Realizacja:

return EnumMember.ConvertToList<YourType>();
 7
Author: LawMan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-02 14:58:49

Różne sposoby rzucania do i z 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);


 }
}
 5
Author: gmail user,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-08 15:18:34

Nie wiem już, skąd biorę część tego rozszerzenia enum, ale pochodzi ono ze stackoverflow. Przepraszam za to! Ale wziąłem ten i zmodyfikowałem go dla enum z flagami. Dla enum z flagami zrobiłem to:

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

Przykład:

[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;
 5
Author: Franki1986,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-07 11:40:50

Może pomóc w przekonwertowaniu dowolnych danych wejściowych na żądane przez użytkownika enum . Załóżmy, że masz enum jak poniżej, które domyślnie int . Proszę dodać wartość Default na początku swojego enum. Który jest używany w helpers medthod, gdy nie znaleziono dopasowania z wartością wejściową.

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

N. B: tutaj staram się parsować wartość do int, ponieważ enum jest domyślnie int Jeśli zdefiniujesz enum w ten sposób, który jest typem byte.

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

Musisz zmienić parsing at helper method from

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

Do

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

Sprawdzam moją metodę pod kątem następujących wejść

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

Sorry for my english

 5
Author: reza.cse08,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-17 12:49:05