열거 형에 int를 캐스팅하는 방법?


3189

C #에서 int캐스트를 어떻게 캐스트 할 수 enum있습니까?

답변:


3792

문자열에서 :

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

정수에서 :

YourEnum foo = (YourEnum)yourInt;

최신 정보:

번호에서 당신은 또한 할 수 있습니다

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

31
@FlySwat, YourEnum동적이고 런타임에만 알려지면 어떻게해야 Enum합니까?
Shimmy Weitzhandler

226
코드가 난독 화되면 Enum.Parse가 작동하지 않습니다. 난독 처리 후 런타임에 문자열이 열거 형 이름과 비교되며이 시점에서 열거 형의 이름이 예상과 다릅니다. 결과적으로 이전에 성공한 위치에서 구문 분석이 실패합니다.
jropella

158
주의 위의 "문자열에서"구문을 사용하고 숫자 인 유효하지 않은 문자열 (예 : "2342342"-열거 형 값이 아닌 것으로 가정)을 전달하면 실제로 오류를 발생시키지 않고 허용합니다! 열거 형 자체에서 올바른 선택이 아니지만 열거 형은 해당 값 (2342342)을 갖습니다.
JoeCool

132
나는이 답변이 약간 날짜가 지난 것 같습니다. 문자열의 경우 var result = Enum.TryParse(yourString, out yourEnum)요즘 실제로 사용해야 합니다 (결과를 확인하여 변환이 실패했는지 확인).
저스틴 T 콘로이

20
호출에 매개 변수 값을 Enum.Parse추가하여 대소 문자를 구분하지 않을 수도 있습니다 true.YourEnum foo = (YourEnum) Enum.Parse(typeof(YourEnum), yourString, true);
Erik Schierboom

900

그냥 캐스트 :

MyEnum e = (MyEnum)3;

Enum.IsDefined 사용하여 범위 내에 있는지 확인할 수 있습니다 .

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

218
Flags 특성을 사용하고 값이 플래그의 조합 인 경우 Enum.IsDefined를 사용할 수 없습니다. Keys.L | Keys.Control
2009

15
에 관해서는 Enum.IsDefined, 위험 할 수 있습니다 : msdn.microsoft.com/en-us/library/ms229025(VS.90).aspx
adrian

3
:이 정의를 선호한다 "반환 지정된 값의 상수는 지정된 열거에 존재하는지 여부를 표시" 에서 MSDN
자궁 경부 세포진

3
... 당신의 말은 다음과 같이 말하고 있기 때문에 당신의 정의가 오도 될 수 있기 때문입니다 : "... 범위 내에 있는지 확인하십시오 ..." 는 시작과 끝 한계를 가진 숫자의 범위를 의미합니다 ...
Pap

3
@ mac9416 나는에서 간결 예를 제공하기 위해 노력했습니다 gist.github.com/alowdon/f7354cda97bac70b44e1c04bc0991bcc - 기본적으로 사용하여 IsDefined입력 값을 확인, 당신은 통과 할 것입니다 나중에 새로운 열거 값을 추가 사람에 취약 자신을 떠나 IsDefined새로운 이후 체크 ( 값이 새 코드에 존재하지만 사용자가 작성한 원래 코드에서 작동하지 않을 수 있습니다. 따라서 코드에서 처리 할 수있는 열거 형 값을 명시 적으로 지정하는 것이 더 안전합니다.
adrian

238

또는 한 줄짜리 대신 확장 방법을 사용하십시오.

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

7
사용자 입력을 처리하려면 Enum.Parse의 오버로드를 호출하는 것이 좋습니다. 이는 비교가 대소 문자를 구분하지 않도록 지정하는 것입니다 (예 : "red"(소문자)를 입력하면이 변경없이 위의 코드가 충돌 함) .)
BrainSlugs83

9
편리하지만 질문은 특히 정수에 대해 묻습니다.
BJury

2
문자열이 정수인 경우에도 작동합니다 (예 : "2"
TruthOf42

2
enumString이 null 인 경우 예외가 발생합니다 (어제와 비슷한 문제가 있음). Parse 대신 TryParse를 사용하십시오. TryParse는 또한 T가 열거 형인지 확인합니다
Justin

이러한 유형의 확장 방법은 System.String네임 스페이스 오염처럼 보입니다
Mr Anderson

160

완전한 대답을 얻으려면 사람들은 열거 형이 .NET에서 내부적으로 어떻게 작동하는지 알아야합니다.

작동 원리

.NET의 열거 형은 값 집합 (필드)을 기본 유형 (기본값은 int)에 매핑하는 구조입니다 . 그러나 실제로 열거 형에 매핑되는 정수 유형을 선택할 수 있습니다.

public enum Foo : short

이 경우 열거 형은 short데이터 유형에 매핑 되므로 메모리에 짧게 저장되어 캐스팅하고 사용할 때 짧게 작동합니다.

IL 관점에서 보면 (normal, int) 열거 형은 다음과 같습니다.

.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를 차지 한다는 것을 의미합니다 -예를 들어 기본 유형의 크기 (실제로는 그보다 더 복잡하지만 야...).

대답

따라서 열거 형에 매핑하려는 정수가있는 경우 런타임은 두 가지 작업 만 수행하면됩니다 .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.WriteLinecall 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();
}

7
나는 이것이 오래된 게시물이라는 것을 알고 있지만 어떻게 C # 에서이 수준의 지식을 얻습니까? 이것이 C # 사양을 읽지 못합니까?
Rolan

20
@Rolan 나는 때때로 더 많은 사람들이 그것을 바란다면 좋겠다. :-) 솔직히 나는 정말로 모른다; 나는 일이 어떻게 작동하는지 이해하고 내가 얻을 수있는 곳이라면 어디에서나 정보를 얻습니다. C # 표준을 읽었지만 Reflector를 사용하여 코드를 정기적으로 디 컴파일하고 (x86 어셈블러 코드를 많이 볼 수도 있음) 수많은 실험을 수행합니다. 또한이 경우 다른 언어에 대해 아는 것이 도움이됩니다. 나는 지금 약 30 년 동안 CS를 해왔으며 어떤 시점에서 어떤 것은 '논리적'이된다. f.ex. 열거 형은 정수 유형이어야합니다. 그렇지 않으면 interop이 중단되거나 성능이 저하 될 수 있습니다.
atlaste

9
소프트웨어 엔지니어링을 제대로 수행하는 비결은 어떻게 작동하는지 아는 것입니다. 저에게 이것은 코드를 작성하면 대략 f.ex로 어떻게 변환되는지 아는 것을 의미합니다. 프로세서 작업 및 메모리 가져 오기 / 쓰기 당신이 그 수준에 도달하는 방법을 묻는다면, 나는 작은 테스트 케이스를 만들어서 더 힘들게 만들고 매번 결과를 예측 한 다음 나중에 테스트 (디 컴파일 등 포함)하려고합니다. 모든 세부 사항과 모든 특성을 파악한 후 (둔한) 표준에 맞는지 확인할 수 있습니다. 적어도 그것은 내 접근 방식 일 것입니다.
atlaste

1
환상적인 답변, 감사합니다! 마지막 코드 샘플에서 o는 객체이므로 런타임에 예외가 발생합니다. int 변수가 짧은 범위 내에있는 한 short로 캐스트 할 수 있습니다.
gravidThoughts

@gravidThoughts 감사합니다. 실제로 이것은 unboxing 작업이므로 설명하는 것과 같은 암시 적 변환은 수행하지 않습니다. 세부 사항을 모르면 C #에서 캐스팅이 혼란 스럽습니다 ... 어쨌든 int! = 때문에 short던질 것입니다 (unboxing 실패). 그렇게 object o = (short)5;하면 유형이 일치하기 때문에 작동합니다. 그것은 범위에 관한 것이 아니라 실제로 유형에 관한 것입니다.
atlaste


64

이 코드를 사용하여 정수에 int를 캐스팅하고 있습니다.

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

최선의 해결책이라고 생각합니다.


1
이것은 좋다. int-backed 열거 형에 유효하지 않은 값을 캐스팅 할 때 예외가 없다는 것에 놀랐습니다.
오리온 엘렌 질

이것은 실제로 최상위 답변과 크게 다르지 않습니다. 이 대답은 문자열을 Enum 유형으로 캐스팅 한 후 Enum.IsDefined 사용에 대해서도 설명합니다. 따라서 문자열이 오류없이 캐스트 되더라도 Enum.IsDefined는 여전히 그것을 잡을 것입니다
Don Cheadle

53

아래는 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

숫자 값의 경우 다음에 관계없이 객체를 반환하므로 더 안전합니다.

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

플래그 열거 형에는 작동하지 않습니다
Seyed Morteza Mousavi


35

비트 마스크 역할을하며 [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()).


1
이 루프는 종료되지 않습니까? flagIterator = 0x00000001, flagIterator = 0x00000002, flagIterator = 0x00000004, ..., flagIterator = 0x40000000, flagIterator = 0x80000000, flagIterator = 0x00000000입니다. 즉, 비트 D31 = 1 인 경우 0으로 오버플로하기 때문에 값은 항상 0x80000000보다 낮습니다. 그런 다음 값을 왼쪽으로 이동하면 0을 유지하므로 0으로 유지됩니다.
Christian Gingras

@christiangingras를 잡아라, 고마워! 이에 대한 답변을 수정했으며 가장 높은 비트가 설정 될 때 (예 : 0x80000000 / Int32.MinValue)
Evan M

27

때로는 MyEnum유형에 개체가 있습니다. 처럼

var MyEnumType = typeof(MyEnumType);

그때:

Enum.ToObject(typeof(MyEnum), 3)

26

다음은 플래그 열거 형 안전 변환 방법입니다.

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

3
이제 C Enum대신 #로 제한하여 C # 7.3으로 개선 할 수 있습니다 struct. 즉, 런타임 검사에 의존 할 필요가 없습니다.
Scott

20

여기에 이미지 설명을 입력하십시오

문자열을 ENUM 또는 int를 ENUM 상수로 변환하려면 Enum.Parse 함수를 사용해야합니다. 다음은 실제로 문자열이 있고 int에 적용되는 YouTube 비디오 https://www.youtube.com/watch?v=4nhx4VwdRDk 입니다.

"red"는 문자열이고 "MyColors"는 색상 상수가있는 색상 ENUM입니다.

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

20

약간 떨어져 원래의 질문에서 받고,하지만 난 찾을 스택 오버플로 질문에 대한 답변 열거에서 가져 오기 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;
}

분명히 열거 형 유형 기능 중 일부는 손실되지만 많은 데이터베이스 ID 상수를 저장하면 꽤 깔끔한 솔루션처럼 보입니다.


5
enums는 더 많은 타입 안전성을 제공하기 때문에 이와 같은 정수 상수의 사용을 대체했습니다
Paul Richards

1
Paul, 이것은 관련된 int 상수 (예 : Database id 상수)를 모아서 매번 사용할 때마다 int로 캐스트하지 않고 직접 사용할 수있는 방법입니다. 유형 정수이며 예를 들어 DatabaseIdsEnum이 아닙니다.
Ted

1
열거 형 유형의 안전을 실수로 우회 할 수있는 상황이 적어도 하나 있습니다.
Thierry

그러나 열거 형은 또한 값이 모두 고유하다는 것을 확인합니다.이 접근 방식에는 부족한 것
derHugo

15

위의 Tawani 유틸리티 클래스와 같은 제네릭을 사용하여 dot.NET 4.0에서 부분 일치하는 정수 또는 문자열을 대상 열거 형으로 구문 분석합니다. 불완전 할 수있는 명령 줄 스위치 변수를 변환하는 데 사용하고 있습니다. 열거 형은 null 일 수 없으므로 논리적으로 기본값을 제공해야합니다. 다음과 같이 호출 할 수 있습니다.

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

참고 : 문제는 정수에 관한 것인데, 언급 한 사람은 Enum.TryParse ()에서 명시 적으로 변환하지 않습니다.


13

문자열에서 : (Enum.Parse가 오래되었습니다. Enum.TryParse를 사용하십시오.)

enum Importance
{}

Importance importance;

if (Enum.TryParse(value, out importance))
{
}

4
이 질문은 특히 정수에 대해 묻습니다.
BJury

4
윌 유는 모든 사람들이 (내가 저항 할 수 없었다) Enum.TryParse이 열거 형의 값 또는 이름의 문자열에서 작동 알려 편집 답변을 기쁘게
JeremyWeir

1
제레미, 위어가 그 일을하고 있어요
huysentruitw

11

다음은 약간 더 나은 확장 방법입니다

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

10

필자의 경우 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에서 Description을 가져 오는 Extension 메서드입니다.

    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

이 열거 확장의 일부를 어디에서 얻었는지 더 이상 알지 못하지만 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;

9

좀 더 견고하게하려면 어떤 유형의 일치 완화를 빌드해야합니다.

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

테스트 사례

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

이것은 좋은 대답입니다. 그것은 지금 당장 페이지 아래에 있다는 것은 부끄러운 일입니다!
MikeBeaton

8

주조 여러 가지 방법 과에서 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);


 }
}

8

입력 데이터를 사용자가 원하는 enum 으로 변환하는 데 도움이됩니다 . 기본적으로 int 와 같은 열거 형이 있다고 가정하십시오 . 열거 형의 처음에 기본값을 추가 하십시오. 입력 값과 일치하는 항목이 없을 때 헬퍼 방법에 사용됩니다.

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

주의 : 열거가 기본으로하기 때문에 나는 여기, INT에 값을 구문 분석하려고 INT 당신이이 같은 열거 정의하면 바이트 유형입니다.

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

내 영어 죄송합니다


8

다음 캐스트 확장 방법이다 Int32Enum.

값이 최대 값보다 높은 경우에도 비트 단위 플래그를 사용합니다. 예를 들어 가능성이 1 , 24 인 열거 형이 있지만 int가 9 인 경우 8이 없으면 1 로 이해합니다 . 이를 통해 코드 업데이트보다 먼저 데이터를 업데이트 할 수 있습니다.

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

6

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

6

당신은 단순히 사용하는 명시 적 변환 INT에 열거 또는 열거 형에 캐스트 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
    }
}

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

3

당신은 아래처럼 좋아합니다 :

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

올바른 값만 캐스트하고 그렇지 않으면 예외를 던질 수 있습니다.

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

IsDefined를 사용하는 것은 캐스팅하는 것보다 비용이 많이 들고 훨씬 더 많은 비용이 소요되므로 사용 여부를 결정하는 구현에 따라 다릅니다.


3

확장 방법을 사용할 수 있습니다.

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

벨로우즈 코드처럼 사용

열거 형 :

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

사용법 :

 string Monday = "Mon";
 int Wednesday = 3;
 var Mon = Monday.ToEnum<DaysOfWeeks>();
 var Wed = Wednesday.ToEnum<DaysOfWeeks>();
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.