2013-05-16 4 views
4

다음 코드가 있습니다. ListKeyValuePair<string, string>이고 지정한 열거 형의 각 열거 형 값의 이름과 값이 필요합니다.Enum을 Int로 캐스트 할 수 없습니다.

public static List<KeyValuePair<string, string>> GetEnumList<TEnum>() where TEnum : struct 
{ 
    if (!typeof(TEnum).IsEnum) 
     throw new ArgumentException("Type must be an enumeration"); 
    List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>(); 
    foreach (TEnum e in Enum.GetValues(typeof(TEnum))) 
     list.Add(new KeyValuePair<string, string>(e.ToString(), ((int)e).ToString())); 
    return list; 
} 

그러나 식 ((int)e).ToString()은 다음 오류를 생성합니다.

Cannot convert type 'TEnum' to 'int'

저는 정수로 enum 인스턴스를 캐스팅하려고합니다. 아무도 왜 이것이 작동하지 않습니다 말해 줄래?

편집 :

내가이 버전을 시도 :

enum Fruit : short 
{ 
    Apple, 
    Banana, 
    Orange, 
    Pear, 
    Plum, 
} 

void Main() 
{ 
    foreach (var x in EnumHelper.GetEnumList<Fruit>()) 
     Console.WriteLine("{0}={1}", x.Value, x.Key); 
} 

public static List<KeyValuePair<string, string>> GetEnumList<TEnum>() where TEnum : struct 
{ 
    if (!typeof(TEnum).IsEnum) 
     throw new ArgumentException("Type must be an enumeration"); 
    List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>(); 
    foreach (TEnum e in Enum.GetValues(typeof(TEnum))) 
    { 
     list.Add(new KeyValuePair<string, string>(e.ToString(), ((int)(dynamic)e).ToString())); 
    } 
    return list; 
} 

그러나 이것은 나에게 오류를 제공합니다

Cannot convert type 'System.Enum' to 'int'

+0

'TEnum'은'int'가 아니기 때문에'where TEnum : struct'는 항상 구조체가 될 것입니다. – WiiMaxx

+0

@WiiMaxx :'struct'는 int 타입의 값 타입을 의미합니다. –

+0

하지만 구조체를 단순한 것으로 이해했기 때문에 [int] (http://msdn.microsoft.com/en-au/library/ah19swz4(v=80) .aspx)에서 어떻게 얻을 수 있습니까? 값을위한 컨테이너 – WiiMaxx

답변

9

TEnum입니다 - 제약 당 - 구조체. enum이되는 것은 보증되지 않습니다. 런타임에서 그 제약 조건을 적용하고 있기 때문에

그러나이 사실을 활용할 수 있습니다 각 열거는 IConvertible는 구현 : 모든 단점을 가지고

foreach (IConvertible e in Enum.GetValues(typeof(TEnum))) 
{ 
    list.Add(new KeyValuePair<string, string>(
     e.ToString(), 
     e.ToType(
      Enum.GetUnderlyingType(typeof(TEnum)), 
      CultureInfo.CurrentCulture).ToString())); 
} 

다른 방법은 다음과 같습니다 먼저 캐스팅 수

object 다음에 int.

열거 형의 기본 유형이 int 이외 인 경우 런타임시 오류가 발생합니다.

int에 캐스팅되기 전에 dynamic에 캐스팅에 의해 극복 될 수있다 : 열거 형 long, ulong 또는 uint가 반환의 경우

:

((int)(dynamic)e).ToString() 

그러나, 이것은 다시 몇 가지 문제가있다 잘못된 값. int 대신 ulong으로 전송하여 문제를 줄일 수 있지만 여전히 부정적인 열거 형 값에 대해 잘못된 값을 반환합니다.

+1

'object' /'Enum'과'int'에 대한 캐스트가 여전히 상자 + unbox라는 점에 유의할만한 가치가 있습니다. 물론 ToString()을 사용한다면 의미가 없을 것입니다; p –

+0

@MarcGravell : 맞습니다. BTW : 캐스트는'Enum' 대신'object'가되어야합니다 - 답을 수정하십시오. –

+0

@JonathanWood : 업데이트를 참조하십시오. –

3

기본 유형을 지정하지 않고이 작업을 수행하는 유일한 방법은 생성 된 메소드를 사용하는 것입니다. Enum 클래스 내의 메서드 심지어 당신은 IConvertable 인터페이스를 사용하려고 할 수 있습니다.당신이 IConvertable를 사용하지 않을 경우

public static List<KeyValuePair<string, string>> GetEnumList<TEnum>() 
      where TEnum : struct, IConvertible 
{ 
    if (!typeof(TEnum).IsEnum) 
     throw new ArgumentException("Type must be an enumeration"); 
    List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>(); 
    foreach (TEnum e in Enum.GetValues(typeof(TEnum))) 
    { 
     list.Add(new KeyValuePair<string, string> 
     (
      e.ToString(), 
      e.ToType(Enum.GetUnderlyingType(typeof(TEnum)), null).ToString() 
     )); 
    } 
    return list; 
} 

하기는 Convert 클래스를 사용하려고 :이 같은 코드에서 그것을 구현할 수

string s = e.ToType(Enum.GetUnderlyingType(typeof(T)), null).ToString(); 

:

// Get underlying type, like int, ulong, etc. 
Type underlyingType = Enum.GetUnderlyingType(typeof(T); 
// Convert the enum to that type. 
object underlyingValue = e.ToType(underlyingType, null); 
// Convert that value to string. 
string s = underlyingValue.ToString(); 

또는 짧은

:

string s = Convert.ChangeType(e, Enum.GetUnderlyingType(typeof(TEnum))).ToString(); 
+0

'Enum.ToObject'는 다른 방법입니다. 숫자 값을 열거 형 멤버로 변환합니다. 컴파일러 오류를 수정 한 후 코드를 실행하면 ArgumentException이 발생합니다. * 제공된 유형은 Enum.Parameter 이름 : enumType *이어야합니다. –

+0

이 중 아무 것도 나를 위해 컴파일되지 않습니다. –

+0

@ 대니얼 : 젠장, 너 맞아 ... 교정오고있어! –

관련 문제