2014-11-24 6 views
6

Ich habe eine Liste von Enum s als IEnumerable<T> und ich muss für jedes Element in einer Schleife und erhalten ihre Beschreibung wie folgt aus:Konvertieren generic T in System.Enum

IEnumerable<T> values = (T[])Enum.GetValues(typeof(T)); 
foreach (Enum value in values) 
{ 
    String mylist = Common.MyExtensions.getEnumDescription(value); 
} 

... 

public static string getEnumDescription(Enum value) 
{ 
    FieldInfo fi = value.GetType().GetField(value.ToString()); 

    DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false); 

    if (attributes != null && attributes.Length > 0) 
    { 
     return attributes[0].Description; 
    } 
    else 
     return value.ToString(); 
} 

Dies erzeugt einen Fehler am foreach Abschnitt

kann "T" nicht in System.Enum konvertieren.

Ist nicht IEnumerable eine Liste von System.Enum an erster Stelle? Welche Art von Besetzung kann den Trick leisten?

+0

Warum nicht verwenden 'T'? –

+0

Sollte Enum nicht T sein? –

+0

Vielleicht ohne Gießen versuchen. So: var Werte = Enum.GetValues ​​(typeof (T)); –

Antwort

-1
foreach(var e in values) 
{ 
    if(e is Enum) 
    { 
     Enum eAsEnum = (Enum)e; 
     String mylist = Common.MyExtensions.getEnumDescription(eAsEnum); 
    } 
} 
+2

Dies wird immer noch den gleichen Fehler bei der Besetzung geben 'Enum eAsEnum = (Enum) e; ' –

0

Betrachten Sie die Art T verwenden, die Sie bereits mit ...

müssen arbeiten
IEnumerable<T> values = (T[])Enum.GetValues(typeof(T)); 
foreach (T value in values) 
{ 
    String mylist = Common.MyExtensions.getEnumDescription(value); 
} 

Sie werden auch getEnumDesciption generic sowie machen.

+1

dann wird der gleiche Fehler an anderer Stelle auftreten:' getEnumDescription (Wert); ' –

4

Ist IEnumerable nicht eine Liste von System.Enum an erster Stelle? Welche Art von Cast kann den Trick machen?

Ja, aber der Compiler kann das nicht sicherstellen. T kann alles zur Laufzeit sein. In Situationen wie dieser in der Regel Sie generische Typ Einschränkungen verwenden, aber where T : Enum ist nicht gültig, so was können Sie tun, ist:

  1. Sie nicht Ihre Methode generisch machen, den Parametertyp zu Enum, wenn Sie arbeiten wollen, mit Aufzählungen nur ändern,
  2. Verwenden where T : struct Einschränkung, um zumindest sicher T zu machen, ist ein Werttyp und überprüfen, ob der Typ Enum innerhalb Ihrer Methode ist, wenn es eine Ausnahme usw. nicht Wurf (dies wird nicht empfohlen)
+3

Für Ihre erste Lösung: Es würde noch mehr Arbeit benötigen:' Enum.GetValues ​​(t) 'wo' t' ist eine Laufzeit 'Type' Instanz, kann nicht in' Enum [] 'umgewandelt werden. Für Ihre zweite Lösung: Das sagt dem OP nicht, wie man den Kompilierungsfehler über eine Umwandlung zwischen 'T' und' Enum' los wird. – hvd

2

ein Weg, die Besetzung zu tun ist:

Enum enumValueError = (Enum)value; 
//compiler error: Cannot convert type 'xxx' to 'System.Enum' 
Enum enumValueNoError = value as Enum; 
//no error, but enumValueNoError will be null if value is not an Enum 
+0

Alternativ ['(int) (Objekt) Wert'] (http://xboxforums.create.msdn.com/forums/t/28060.aspx) – KyleMit

0

ich Ihr für so etwas suchen erraten (geändert, um die Implementierung ein Bit):

public enum Test 
{ 
    [Description("This")] 
    A, 
    B, 
    C, 
    D 
} 

private IEnumerable<string> GetEnumDescription<T>() 
{ 
    var type = typeof(T); 

    if (!type.IsEnum) throw new ArgumentException("Only Enum types allowed"); 

    foreach (var value in Enum.GetValues(type).Cast<Enum>()) 
    { 
     yield return getEnumDescription(value); 
    } 
} 

public string getEnumDescription(Enum value) 
{ 
    FieldInfo fi = value.GetType().GetField(value.ToString()); 

    DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false); 

    if (attributes != null && attributes.Length > 0) 
    { 
     return attributes[0].Description; 
    } 
    else 
    { 
     return value.ToString(); 
    } 
} 

und der Anruf wird wie folgt aussehen:

var desc = GetEnumDescription<Test>(); // "This", "B", "C", "D"