캐스팅하지 않고 바람직하게는 문자열을 구문 분석하지 않고 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
직접 상속 관계가 없으므로 유형 시스템 내에서 명시 적 캐스트가 정확할 수 없습니다.Int32
ValueType
답변
객체로 캐스팅 한 다음 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 안에 맞지 않을 때 무엇을해야할지 결정해야합니다. 캐스팅은 괜찮다고 생각하지만 여전히 몇 가지 문제가 있습니다.
- int (long 및 ulong)보다 큰 필드 공간을 가진 유형을 기반으로하는 열거 형의 경우 일부 열거 형이 동일한 값으로 평가 될 수 있습니다.
- int.MaxValue보다 큰 숫자를 캐스팅하면 선택된 영역에있는 경우 예외가 발생합니다.
여기에 제 제안이 있습니다.이 기능을 어디에 노출 시킬지 결정하기 위해 독자에게 맡기겠습니다. 도우미 또는 확장으로.
public int ToInt(Enum e)
{
unchecked
{
if (e.GetTypeCode() == TypeCode.UInt64)
return (int)Convert.ToUInt64(e);
else
return (int)Convert.ToInt64(e);
}
}