2012-04-24 20 views
11

So come eseguire il ciclo attraverso l'elenco enum delle proprietà, ma come faccio a scorrere tra tutte le proprietà enum "selezionate"? Ad esempio, se uno ha fatto Prop1 | Prop2 contro public enum Foo { Prop1; Prop2; Prop3 }, come potrei ottenere questo?Ciclo attraverso i valori Enum "selezionati"?

Questo è quello che ho adesso:

var values = Enum.GetValues(typeof(FileStatus)).Cast<FileStatus>(); 
foreach (var value in values) 
{ 
} 

Esso scorre tutte le proprietà enum, ma mi piacerebbe ciclo solo quelli che sono stati "selezionati".

Aggiornamento: [Flags] l'attributo è stato impostato.

Aggiornamento 2: l'enumerazione contiene un gran numero di proprietà, non posso e non scriverò/hardcode un singolo controllo di proprietà, invece voglio scorrere dinamicamente ciascuna di esse e controllare se la mia istanza di enum Bar contiene il set di articoli in loop.

+0

Forse ti infili il FlagsAttribute sul enum? – scottheckel

+0

@Hexxagonal: non importa. Tuttavia, l'assegnazione esplicita di valori è molto importante. –

+0

@Hexxagonal Questo è davvero più opzionale di qualsiasi altra cosa. Le enumerazioni possono o meno essere ciascuna delle potenze di due. Indipendentemente dal fatto che le bandiere att. è impostato * dovrebbe * importare, ma in realtà non lo è. – Servy

risposta

23

Come circa la seguente:

FileStatus status = FileStatus.New|FileStatus.Amazing; 

foreach (FileStatus x in Enum.GetValues(typeof(FileStatus))) 
{ 
    if (status.HasFlag(x)) Console.WriteLine("{0} set", x); 
} 

O in un sol colpo solo LINQ:

var flags = Enum.GetValues(typeof(FileStatus)) 
       .Cast<FileStatus>() 
       .Where(s => status.HasFlag(s)); 
+0

+1, concordo, stampa solo se la bandiera è impostata. – Tejs

+0

Funziona meravigliosamente! 'if' passa solo quando la proprietà enum loop è impostata per lo stato! – Tower

3

Supponendo di avere questo set come una maschera di bit, quindi semplicemente "e" i valori determinerebbero quali sono selezionati.

SomeEnum bitmask = value; 

if(bitmask & SomeEnum.Value1 > 0) 
    // SomeEnum.Value1 was set 
+3

'bitmask.HasFlag (SomeEnum.Value1)' è più leggibile e fa la stessa cosa –

+0

Buon punto! Tuttavia, è bello capire esattamente cosa sta facendo sotto il cofano, per completezza. – Tejs

1
FileStatus someValue = ...; 
var selectedValues = new List<FileStatus>(); 
var allValues = Enum.GetValues(typeof(FileStatus)).Cast<FileStatus>(); 
foreach (var value in allValues) 
{ 
    if(someValue & value != 0)//note bitwise AND, not logical AND. 
    { 
    selectedValues.Add(value); 
    //this value is selected. You can stick it in a List or do whatever with it. 
    } 
} 
0

Si avrebbe bisogno di segnare l'enum con l'attributo Flags. Per ottenere i valori che è possibile utilizzare yourObject.EnumProperty.HasFlag metodo, ad esempio:

class Program 
{ 
    [Flags] 
    public enum Bar { Prop1, Prop2, Prop3 } 

    public class Foo 
    { 
     public Bar SelectedBar { get; set; } 
    } 

    static void Main(string[] args) 
    { 
     var foo = new Foo(); 
     foo.SelectedBar = Bar.Prop1 | Bar.Prop2; 

     foo.SelectedBar.HasFlag(Bar.Prop1); //true 
     foo.SelectedBar.HasFlag(Bar.Prop2); //true 
     foo.SelectedBar.HasFlag(Bar.Prop3); //false 
    } 
} 
3
[Flags] 
public enum Foo 
{ 
    Prop1 = 1, 
    Prop2 = 1 << 1, 
    Prop3 = 1 << 2 
} 

public static class FooExtensions 
{ 
    private static readonly Foo[] values = (Foo[])Enum.GetValues(typeof(Foo)); 

    public static IEnumerable<Foo> GetComponents(this Foo value) 
    { 
     return values.Where(v => (v & value) != 0); 
    } 
} 

public static class Program 
{ 
    public static void Main(string[] args) 
    { 
     var foo = Foo.Prop1 | Foo.Prop3; 

     var components = foo.GetComponents().ToArray(); 
    } 
} 
Problemi correlati