[c#] System.Enum에서 기본 정수로 변환하는 방법은 무엇입니까?

캐스팅하지 않고 바람직하게는 문자열을 구문 분석하지 않고 System.Enum 파생 형식을 해당 정수 값으로 변환하는 일반 메서드를 만들고 싶습니다.

예를 들어, 내가 원하는 것은 다음과 같습니다.

// Trivial example, not actually what I'm doing.
class Converter
{
    int ToInteger(System.Enum anEnum)
    {
        (int)anEnum;
    }
}

그러나 이것은 작동하지 않는 것 같습니다. Resharper는 ‘System.Enum’형식의 식을 ‘int’형식으로 캐스팅 할 수 없다고보고합니다.

이제이 솔루션을 생각해 냈지만 더 효율적인 방법을 원합니다.

class Converter
{
    int ToInteger(System.Enum anEnum)
    {
        return int.Parse(anEnum.ToString("d"));
    }
}

어떤 제안?



답변

캐스팅하고 싶지 않다면

Convert.ToInt32()

트릭을 할 수 있습니다.

직접 캐스트 (를 통해 (int)enumValue)는 불가능합니다. 열거 다른 기본 유형을 가질 수 있기 때문에이 또한 “위험”이 될 것이라고 주 ( int, long, byte…).

보다 공식적으로 : (둘 다 s 임에도 불구하고) System.Enum직접 상속 관계가 없으므로 유형 시스템 내에서 명시 적 캐스트가 정확할 수 없습니다.Int32ValueType


답변

객체로 캐스팅 한 다음 int로 캐스팅하여 작동하도록했습니다.

public static class EnumExtensions
{
    public static int ToInt(this Enum enumValue)
    {
        return (int)((object)enumValue);
    }
}

이것은 추악하고 아마도 최선의 방법은 아닙니다. 나는 더 나은 것을 생각 해낼 수 있는지보기 위해 그것을 계속 엉망으로 만들 것이다 ….

편집 : Convert.ToInt32 (enumValue)도 작동한다는 것을 게시하려고했으며 MartinStettner가 나를 이겼 음을 알았습니다.

public static class EnumExtensions
{
    public static int ToInt(this Enum enumValue)
    {
        return Convert.ToInt32(enumValue);
    }
}

테스트:

int x = DayOfWeek.Friday.ToInt();
Console.WriteLine(x); // results in 5 which is int value of Friday

편집 2 : 의견에서 누군가가 이것이 C # 3.0에서만 작동한다고 말했습니다. 방금 VS2005에서 이것을 다음과 같이 테스트했으며 작동했습니다.

public static class Helpers
{
    public static int ToInt(Enum enumValue)
    {
        return Convert.ToInt32(enumValue);
    }
}

    static void Main(string[] args)
    {
        Console.WriteLine(Helpers.ToInt(DayOfWeek.Friday));
    }


답변

당신이 변환해야하는 경우 어떤 (모든 열거 형에 의해 뒷받침되지는 기본 유형 열거 int) 당신은 사용할 수 있습니다 :

return System.Convert.ChangeType(
    enumValue,
    Enum.GetUnderlyingType(enumValue.GetType()));


답변

도우미 메서드를 사용하여 바퀴를 재발 명해야하는 이유는 무엇입니까? enum값을 기본 유형 으로 캐스팅하는 것은 완벽하게 합법적 입니다.

타이핑이 적고 사용하기가 더 읽기 쉽습니다.

int x = (int)DayOfWeek.Tuesday;

… 같은 것보다 …

int y = Converter.ToInteger(DayOfWeek.Tuesday);
// or
int z = DayOfWeek.Tuesday.ToInteger();


답변

여기 내 대답 에서 :

다음 e과 같이 주어 집니다.

Enum e = Question.Role;

그런 다음 작동합니다.

int i = Convert.ToInt32(e);
int i = (int)(object)e;
int i = (int)Enum.Parse(e.GetType(), e.ToString());
int i = (int)Enum.ToObject(e.GetType(), e);

마지막 두 개는 아주 추합니다. 첫 번째는 더 읽기 쉬워야하지만 두 번째는 훨씬 빠릅니다. 또는 확장 방법이 두 세계 모두에서 최고 일 수 있습니다.

public static int GetIntValue(this Enum e)
{
    return e.GetValue<int>();
}

public static T GetValue<T>(this Enum e) where T : struct, IComparable, IFormattable, IConvertible, IComparable<T>, IEquatable<T>
{
    return (T)(object)e;
}

이제 다음을 호출 할 수 있습니다.

e.GetValue<int>(); //or
e.GetIntValue();


답변

a에서로 캐스팅 System.Enum하면 int잘 작동합니다 ( MSDN 에도 있습니다 ). 아마도 Resharper 버그 일 것입니다.


답변

Enum은 byte, sbyte, short, ushort, int, uint, long 및 ulong으로 제한되므로 몇 가지 가정을 할 수 있습니다.

사용 가능한 가장 큰 컨테이너를 사용하여 변환 중에 예외를 피할 수 있습니다. 불행히도, ulong은 음수로 폭발하고 long은 long.MaxValue와 ulong.MaxValue 사이의 숫자로 폭발하기 때문에 어떤 컨테이너를 사용할지는 명확하지 않습니다. 기본 유형에 따라 이러한 선택을 전환해야합니다.

물론 결과가 int 안에 맞지 않을 때 무엇을해야할지 결정해야합니다. 캐스팅은 괜찮다고 생각하지만 여전히 몇 가지 문제가 있습니다.

  1. int (long 및 ulong)보다 큰 필드 공간을 가진 유형을 기반으로하는 열거 형의 경우 일부 열거 형이 동일한 값으로 평가 될 수 있습니다.
  2. int.MaxValue보다 큰 숫자를 캐스팅하면 선택된 영역에있는 경우 예외가 발생합니다.

여기에 제 제안이 있습니다.이 기능을 어디에 노출 시킬지 결정하기 위해 독자에게 맡기겠습니다. 도우미 또는 확장으로.

public int ToInt(Enum e)
{
  unchecked
  {
    if (e.GetTypeCode() == TypeCode.UInt64)
      return (int)Convert.ToUInt64(e);
    else
      return (int)Convert.ToInt64(e);
  }
}