2012-04-24 30 views
11

Sé cómo recorrer toda la lista de propiedades, pero ¿cómo recorrería todas las propiedades enumeradas "seleccionadas"? Por ejemplo, si uno hizo Prop1 | Prop2 contra public enum Foo { Prop1; Prop2; Prop3 }, ¿cómo lo conseguiría?Pasa por los valores Enum "seleccionados"?

Esto es lo que tengo ahora:

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

Se coloca a través de todas las propiedades de enumeración, pero me gustaría bucle sólo los que fueron "seleccionados".

Actualización: [Flags] atributo se estableció.

Actualización 2: La enumeración contiene un gran número de propiedades, no puedo y no escribiré/codificaré una sola comprobación de propiedad, en su lugar quiero pasar dinámicamente por cada una de ellas y comprobar si mi instancia enum Bar contiene el conjunto de elementos en bucle.

+0

¿Usted se pega la FlagsAttribute en la enumeración? – scottheckel

+0

@Hexxagonal: no importa. Sin embargo, asignar valores explícitamente importa mucho. –

+0

@Hexxagonal Eso es realmente más opcional que nada. Las enumeraciones pueden o no ser poderes de dos. Si las banderas están o no está configurado * debería * importar, pero realmente no es así. – Servy

Respuesta

23

¿Qué hay de lo siguiente:

FileStatus status = FileStatus.New|FileStatus.Amazing; 

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

O en una cayó sola vez LINQ:

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

+1, estoy de acuerdo, solo se imprime si la bandera está configurada. – Tejs

+0

¡Funciona maravillosamente! 'if' solo pasa cuando la propiedad enum enlazada está configurada para el estado! – Tower

3

Suponiendo que tiene este conjunto como una máscara de bits, simplemente "y" -ing los valores determinarían cuáles están seleccionados.

SomeEnum bitmask = value; 

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

'bitmask.HasFlag (SomeEnum.Value1)' es más legible y hace lo mismo –

+0

¡Buen punto! Aún así, es bueno entender exactamente lo que está haciendo bajo el capó, para completarlo. – 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

Usted tendría que marcar la enumeración con Flags atributo. Para obtener los valores que puede utilizar yourObject.EnumProperty.HasFlag método, por ejemplo:

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(); 
    } 
} 
Cuestiones relacionadas