Вставить int для перечисления в С#

Как int можно передать в enum в С#?

2749
задан 27 авг. '08 в 6:58
источник поделиться
23 ответов

Из строки:

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

Из int:

YourEnum foo = (YourEnum)yourInt;

Update:

Из числа вы также можете

YourEnum foo = (YourEnum)Enum.ToObject(typeof(YourEnum) , yourInt);
3310
ответ дан 27 авг. '08 в 6:59
источник

Просто бросьте его:

MyEnum e = (MyEnum)3;

Вы можете проверить, находится ли он в диапазоне, используя Enum.IsDefined:

if (Enum.IsDefined(typeof(MyEnum), 3)) { ... }
766
ответ дан 27 авг. '08 в 7:01
источник

В качестве альтернативы используйте метод расширения вместо однострочного:

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

Применение:

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

ИЛИ

string color = "Red";
var colorEnum = color.ToEnum<Color>();
211
ответ дан 11 нояб. '11 в 16:27
источник

Я думаю, чтобы получить полный ответ, люди должны знать, как enums работают внутри .NET.

Как работает материал

Перечисление в .NET - это структура, которая отображает набор значений (полей) в базовый тип (по умолчанию это int). Тем не менее, вы можете выбрать тип интеграла, который соответствует вашему перечислению:

public enum Foo : short

В этом случае перечисление преобразуется в тип данных short, что означает, что он будет храниться в памяти как короткий и будет вести себя как короткий, когда вы используете и используете его.

Если вы посмотрите на него с точки зрения IL, (enum, int) enum выглядит следующим образом:

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

Что следует обратить ваше внимание на то, что value__ хранится отдельно от значений перечисления. В случае перечисления Foo выше тип value__ - int16. Это в основном означает, что вы можете хранить все, что хотите, в перечислении, , если типы соответствуют.

В этот момент я хотел бы указать, что System.Enum - это тип значения, что в основном означает, что BarFlag будет занимать 4 байта в памяти, а Foo займет 2 - например. размер базового типа (это на самом деле более сложный, чем тот, но эй...).

Ответ

Итак, если у вас есть целое число, которое вы хотите сопоставить с перечислением, время выполнения должно делать только 2 вещи: скопируйте 4 байта и назовите это что-то еще (имя перечисления). Копирование является неявным, поскольку данные хранятся как тип значения - это в основном означает, что если вы используете неуправляемый код, вы можете просто обменять перечисления и целые числа без копирования данных.

Чтобы сделать это безопасным, я считаю, что наилучшей практикой известно, что базовые типы являются одинаковыми или неявно конвертируемыми и для обеспечения наличия значений перечисления (они не отмечены по умолчанию!).

Чтобы узнать, как это работает, попробуйте следующий код:

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

Обратите внимание, что также работает отбрасывание на e2! Из перспективы компилятора выше это имеет смысл: поле value__ просто заполняется либо 5, либо 6, а когда Console.WriteLine вызывает ToString(), имя e1 разрешается, а имя e2 - нет.

Если это не то, что вы намеревались, используйте Enum.IsDefined(typeof(MyEnum), 6), чтобы проверить, действительно ли значение, которое вы создаете, сопоставляет определенному перечислению.

Также обратите внимание, что я явно о базовом типе перечисления, хотя компилятор действительно проверяет это. Я делаю это, чтобы я не сталкивался с неожиданностями в будущем. Чтобы увидеть эти сюрпризы в действии, вы можете использовать следующий код (на самом деле я видел, как это произошло в коде базы данных):

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();
}
132
ответ дан 03 апр. '14 в 10:39
источник

Возьмем следующий пример:

int one = 1;
MyEnum e = (MyEnum)one;
98
ответ дан 27 авг. '08 в 7:00
источник

Я использую этот кусок кода для преобразования int в свой список перечислений:

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

Я считаю это лучшим решением.

58
ответ дан 21 окт. '11 в 13:05
источник

Ниже приведен хороший класс утилиты для 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;
    }
}
47
ответ дан 07 сент. '10 в 7:42
источник

Для числовых значений это безопаснее, так как он вернет объект независимо от того, что:

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;
    }
}
40
ответ дан 21 февр. '13 в 18:22
источник

Если вы готовы к созданию 4.0 .NET, здесь есть новая функция Enum.TryParse(), которая очень полезна и хорошо работает с [Flags] атрибут. См. Метод Enum.TryParse(String, TEnum%)

39
ответ дан 01 нояб. '11 в 17:58
источник

Если у вас есть целое число, которое действует как битовая маска и может представлять одно или несколько значений в перечислении [Flags], вы можете использовать этот код для анализа значений отдельных флагов в списке:

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

Обратите внимание, что это предполагает, что базовый тип enum является 32-разрядным целым числом со знаком. Если бы это был другой числовой тип, вам пришлось бы изменить жестко запрограммированный 32, чтобы отразить биты этого типа (или получить его программным путем, используя Enum.GetUnderlyingType()).

26
ответ дан 13 апр. '11 в 23:13
источник

Иногда у вас есть объект типа MyEnum. Как

var MyEnumType = typeof(MyEnumType);

Тогда:

Enum.ToObject(typeof(MyEnum), 3)
24
ответ дан 02 июля '10 в 17:41
источник

Это безопасный метод преобразования с учетом перечисления флагов:

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;
}
20
ответ дан 30 марта '15 в 13:08
источник

enter image description here

Чтобы преобразовать строку в ENUM или int в константу ENUM, нам нужно использовать функцию Enum.Parse. Вот видео youtube https://www.youtube.com/watch?v=4nhx4VwdRDk, которые на самом деле демонстрируются со строкой, и то же самое относится к int.

Код идет, как показано ниже, где "красный" - это строка, а "MyColors" - это цвет ENUM, который имеет цветовые константы.

MyColors EnumColors = (MyColors)Enum.Parse(typeof(MyColors), "Red");
19
ответ дан 05 февр. '14 в 15:15
источник

Слегка уйти от исходного вопроса, но я нашел ответ на вопрос Qaru Получить значение int из перечисления. Создайте статический класс с помощью свойств public const int, позволяя вам легко собрать кучу связанных констант int, а затем не использовать их при int при их использовании.

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

Очевидно, что некоторые функции типа перечисления будут потеряны, но для хранения связки констант идентификатора базы данных это выглядит как довольно аккуратное решение.

16
ответ дан 17 июля '14 в 17:39
источник

Это разделяет целые числа или строки на целевое перечисление с частичным совпадением в dot.NET 4.0 с использованием дженериков, таких как класс утилиты Tawani выше. Я использую его для преобразования переменных ключа командной строки, которые могут быть неполными. Поскольку перечисление не может быть нулевым, вы должны логически предоставить значение по умолчанию. Его можно назвать так:

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

Здесь код:

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: Вопрос о целых числах, о которых никто не упоминал, также будет явно преобразован в Enum.TryParse()

12
ответ дан 30 июля '14 в 23:02
источник

Из строки: (Enum.Parse устарел, используйте Enum.TryParse)

enum Importance
{}

Importance importance;

if (Enum.TryParse(value, out importance))
{
}
12
ответ дан 21 нояб. '14 в 3:32
источник

В моем случае мне нужно было вернуть перечисление из службы WCF. Мне также понадобилось дружественное имя, а не только enum.ToString().

Здесь мой класс 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;
    }
}

Здесь используется метод расширения, который получает описание из 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();
        }
    }

Реализация:

return EnumMember.ConvertToList<YourType>();
9
ответ дан 02 июля '14 в 17:58
источник

Ниже приведен немного лучший метод расширения

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;
        }
9
ответ дан 16 дек. '16 в 9:59
источник

Различные способы передачи в и из 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);


 }
}
7
ответ дан 08 янв. '14 в 18:18
источник

Я больше не знаю, где я получаю часть этого расширения enum, но это из stackoverflow. Прошу прощения за это! Но я взял это и изменил его для перечислений с помощью флагов. Для перечислений с флажками я сделал это:

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

Пример:

[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;
7
ответ дан 07 янв. '16 в 14:40
источник

Он может помочь вам преобразовать любые входные данные в желаемый перечисление пользователя. Предположим, что у вас есть перечисление вроде ниже, по умолчанию int. Добавьте сначала Default значение по умолчанию. Используется в помощниках medthod, когда нет совпадения с входным значением.

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: Здесь я пытаюсь проанализировать значение в int, потому что enum по умолчанию int Если вы определяете перечисление, подобное типу byte.

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

Вам нужно изменить разбор по вспомогательному методу из

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

к

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

Я проверяю свой метод на следующие входы

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

извините за мой английский

6
ответ дан 17 нояб. '16 в 15:49
источник

простой и понятный способ приведения int к enum в С#:

 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));
        }
    }
3
ответ дан 08 дек. '18 в 8:06
источник

Вы просто используете явное преобразование Cast int в enum или enum в 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           
        }
    }
0
ответ дан 01 февр. '19 в 13:15
источник

Другие вопросы по меткам или Задайте вопрос