program story

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

inputbox 2020. 9. 9. 08:00
반응형

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

Why do you need to reinvent the wheel with a helper method? It's perfectly legal to cast an enum value to its underlying type.

It's less typing, and in my opinion more readable, to use...

int x = (int)DayOfWeek.Tuesday;

...rather than something like...

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

From my answer here:

Given e as in:

Enum e = Question.Role;

Then these work:

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

The last two are plain ugly. The first one should be more readable, though the second one is much faster. Or may be an extension method is the best, best of both worlds.

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

Now you can call:

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

Casting from a System.Enum to an int works fine for me (it's also on the MSDN). Perhaps it's a Resharper bug.


Since Enums are restricted to byte, sbyte, short, ushort, int, uint, long and ulong, we can make some assumptions.

We can avoid exceptions during conversion by using the largest available container. Unfortunately, which container to use is not clear because ulong will blow up for negative numbers and long will blow up for numbers between long.MaxValue and ulong.MaxValue. We need to switch between these choices based on the underlying type.

Of course, you still need to decide what to do when the result doesn't fit inside an int. I think casting is okay, but there are still some gotchas:

  1. for enums based on a type with a field space larger than int (long and ulong), it's possible some enums will evaluate to the same value.
  2. casting a number larger than int.MaxValue will throw an exception if you are in a checked region.

Here's my suggestion, I'll leave it to the reader to decide where to expose this function; as a helper or an extension.

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

Don't forget that the Enum type itself has a bunch of static helper functions in it. If all you want to do is convert an instance of the enum to its corresponding integer type, then casting is probably the most efficient way.

I think ReSharper is complaining because Enum isn't an enumeration of any particular type, and enumerations themselves derive from a scalar valuetype, not Enum. If you need adaptable casting in a generic way, I would say this could suite you well (note that the enumeration type itself is also included in the generic:

public static EnumHelpers
{
    public static T Convert<T, E>(E enumValue)
    {
        return (T)enumValue;
    }
}

This could then be used like so:

public enum StopLight: int
{
    Red = 1,
    Yellow = 2,
    Green = 3
}

// ...

int myStoplightColor = EnumHelpers.Convert<int, StopLight>(StopLight.Red);

I can't say for sure off the top of my head, but the above code might even be supported by C#'s type inference, allowing the following:

int myStoplightColor = EnumHelpers.Convert<int>(StopLight.Red);

참고URL : https://stackoverflow.com/questions/908543/how-to-convert-from-system-enum-to-base-integer

반응형