2016-05-12 12 views
1

Ich habe ein enum mit dem [Flag] Attribut definiert.Verwenden von Where on Enum-Werten

Bei einem ganzzahligen Wert würde ich gerne alle enum Werte für die Bits ausgeben, die im Ganzzahlwert gesetzt sind.

Hier ist, was ich bisher habe.

string s = string.Join(", ", Enum.GetValues(typeof(MyEnumType)).OfType<Enum>() 
           .Where(x => (MyIntValue & (int)x) != 0)); 

Aber die Typumwandlung zu int in der letzten Zeile gibt mir die folgende Fehlermeldung.

Kann nicht Typ 'System.Enum' auf 'int'

Ich möchte konvertieren Microsoft alle Framework-Code ersetzen würde, die Array für Typen zurückgibt, die LINQ unterstützen.

Aber gibt es eine einfache Möglichkeit, dies zu tun?

+1

Warum nicht '.OfType ()' statt '.OfType ()'? –

+0

Wenn Sie Ihren int-Wert an Enum übergeben und ToString() aufrufen, sollten Sie genau das tun, was Sie wollen. Siehe http://stackoverflow.com/questions/8447/what-does-the-flags-enum-attribute-mean-in-c?rq=1 – devio

+0

"Ich wünschte, Microsoft würde den gesamten Framework-Code, der Array zurückgibt, ersetzen von Typen, die LINQ unterstützen. " - Und was sollten sie mit all dem Legacy-Code tun, der vor Linq geschrieben wurde? Lassen Sie den ganzen Code, der über die Jahre entwickelt wurde, plötzlich brechen? –

Antwort

2

Zu viel LINQ Denkweise, so dass manchmal wir vergessen, woher wir kommen :) Ausgehend von der allerersten .NET-Version gibt Enum.GetValues(typeof(MyEnum)) eigentlich MyEnum[] zurück, also brauchen Sie weder OfType, noch Cast, sondern einfach C# cast:

string s = string.Join(", ", ((MyEnum[])Enum.GetValues(typeof(MyEnumType))) 
    .Where(x => (MyIntValue & (int)x) != 0)); 

Da das typeof mit dem Gießen auf die gleiche Art kombiniert ist ziemlich ärgerlich, von einer sehr langen Zeit, die ich diesen kleinen Helfer in der Tasche haben:

public static class EnumInfo 
{ 
    public static T[] GetValues<T>() where T : struct // I (and not only) wish I could say where T : enum 
    { 
     return (T[])Enum.GetValues(typeof(T)); 
    } 
} 

, die mir erlaubt, zu verwenden, viel prägnanter

string s = string.Join(", ", EnumInfo.GetValues<MyEnumType>() 
    .Where(x => (MyIntValue & (int)x) != 0)); 
+0

Sollte Ihre 'GetValues ​​()' Methode etwas anderes als 'T' zurückgeben? Zum Beispiel, 'T []'? –

+0

@ JonathanWood Absolut, danke (Sie wissen, wie es ist, wenn Sie den Code direkt im Browser schreiben :) –

3

Casting auf MyEnumType anstelle der allgemeinen Enum sollte das Problem beheben:

string s = string.Join(
    ", ", 
    Enum.GetValues(typeof(MyEnumType)) 
     .OfType<MyEnumType>() 
     .Where(x => (MyIntValue & (int)x) != 0)); 

Sie wirklich Cast statt OfType verwendet werden sollte, da Sie sicher sind, dass die Einzelteile sind vom Typ MyEnumType.

+0

Ja, du hast Recht. Dieser Code ist immer noch zu unordentlich und wird zu langsam ausgeführt. Microsoft muss das Framework aktualisieren. Vielen Dank. –

+0

Sie sind willkommen –

+0

@ JonathanWood Welcher Teil führt "zu langsam" aus und wie schlagen Sie vor, dass Microsoft es repariert? –

0

Sie können Ihre eigene GetValues ​​Methode schreiben, die Generika zu bekommen verwendet, was Sie brauchen:

public static class EnumUtil 
{ 
    public static IEnumerable<T> GetValues<T>() 
    { 
     foreach(T enumVal in Enum.GetValues(typeof(T))) 
     { 
      yield return enumVal; 
     } 
    } 
} 

die dann wie so verwendet wird:

var s = string.Join(", ", EnumUtil.GetValues<TestEnum>() 
    .Where(x => (myIntValue & (int)x) != 0)); 
Verwandte Themen