2011-09-19 7 views
30

Me pregunto de una manera genérica para establecer todos los bits del indicador enum en 1. Solo me gustaría tener un enum que devuelve todas las comparaciones, independientemente de otras enumeraciones.Cómo configurar todos los bits de enum flag

Y este código funciona;

[Flags] 
public enum SomeRightEnum : uint 
{ 
    CanDoNothing = 0, 
    CanDoSomething = 1 << 0, 
    CanDoSomethingElse = 1 << 1, 
    CanDoYetAnotherThing = 1 << 2, 
    ... 
    DoEverything = 0xFFFFFFFF 
} 

Pero en el código anterior, ya que es uint establecemos el número de s "F", que no funcionaría si era int.

Así que voy a apreciar una forma genérica de configuración de todos los bits de bandera enum a 1, independientemente del tipo de datos (i nt, int64, uint etc)

+1

Hmmm. La intención de las enumeraciones es describir opciones mutuamente excluyentes. Parece que los estás usando como abreviatura de un montón de máscaras de bits. –

+1

@AFgone Está utilizando el atributo [Flags] en la enumeración ¿verdad? –

+1

@Oli El atributo [Flags] en la enumeración está diseñado para este fin. –

Respuesta

47

Lo más rápido es probable que:

enum Foo 
{ 
    blah = 1, 
    .... 
    all = ~0 
} 

Para enumeración basada sin firmar:

enum Foo : uint 
{ 
    blah = 1, 
    .... 
    all = ~0u; 
} 
+0

cuando intento esto, dice "El valor constante '-1' no se puede convertir en un 'uint'" – AFgone

+1

Solo echar entonces, por ejemplo, 'unchecked ((uint) ~ 0)' – leppie

+0

muchas gracias, esto es lo que estaba buscando – AFgone

3
internal static class Program 
{ 
    private static void Main() 
    { 
     Console.WriteLine(Foo.Everything.HasFlag(Foo.None)); // False 
     Console.WriteLine(Foo.Everything.HasFlag(Foo.Baz)); // True 
     Console.WriteLine(Foo.Everything.HasFlag(Foo.Hello)); // True 
    } 
} 

[Flags] 
public enum Foo : uint 
{ 
    None = 1 << 0, 
    Bar = 1 << 1, 
    Baz = 1 << 2, 
    Qux = 1 << 3, 
    Hello = 1 << 4, 
    World = 1 << 5, 
    Everything = Bar | Baz | Qux | Hello | World 
} 

Fue esto lo que quería?

+0

pero esto no es independientemente de otras enumeraciones, cuando edito o elimino las enumeraciones también tengo que cambiar "Todo" – AFgone

5

En caso de que alguien se pregunta: que tenía que hacer la misma construcción de un EnumConverter enlazables para WPF.
Como no sé lo que significan los valores en Reflection, necesitaba poder cambiar manualmente los valores (vinculándolos a una casilla de verificación pe)
Hay un problema al establecer el valor de una enumeración marcada en -1 para establecer todos los bits.
Si lo configura en -1 y desmarca todos los valores, no dará como resultado 0 porque todos los bits no utilizados no están desprotegidos.
Esto es lo que mejor funciona para mi situación.

SomeRightEnum someRightEnum = SomeRightEnum.CanDoNothing; 
Type enumType = someRightEnum.GetType(); 
int newValue = 0; 
var enumValues = Enum.GetValues(enumType).Cast<int>().Where(e => e == 1 || e % 2 == 0); 
foreach (var value in enumValues) 
{ 
    newValue |= value; 
} 
Console.WriteLine(newValue); 

O si usted quiere un método de extensión:

public static class FlagExtensions 
{ 
    public static TEnum AllFlags<TEnum>(this TEnum @enum) 
     where TEnum : struct 
    { 
     Type enumType = typeof(TEnum); 
     long newValue = 0; 
     var enumValues = Enum.GetValues(enumType); 
     foreach (var value in enumValues) 
     { 
      long v = (long)Convert.ChangeType(value, TypeCode.Int64); 
      if(v == 1 || v % 2 == 0) 
      { 
       newValue |= v; 
      } 
     } 
     return (TEnum)Enum.ToObject(enumType , newValue); 
    } 
} 
+0

lo convierten en un método de extensión llamado 'AllFlags' que extiende la clase del sistema' enum'. entonces podría usarse cuidadosamente 'enum.AllFlags (typeof (MyEnum)) 'no? –

+0

@ v.oddou He actualizado mi respuesta con una extensión genérica que devuelve el valor (inmutable). También eliminé un error para omitir los valores que no son de marca. – Silvermind

18
[Flags] 
public enum MyEnum 
{ 
    None = 0, 
    First = 1 << 0, 
    Second = 1 << 1, 
    Third = 1 << 2, 
    Fourth = 1 << 3, 
    All = ~(-1 << 4) 
} 
+0

Me gusta esta opción incluso mejor que mi opción '-1' habitual. Estaba usando una enumeración para realizar un seguimiento de las tareas solicitadas y eliminar el marcador cuando se completó la tarea. Mi plan era usar el resultado como el código de salida. Entonces esto ayuda con el mantenimiento de las tareas enum. – Schmalls

+1

Prefiero 'All = ~ (~ 0 << 4)' porque es un poco más claro. No todo el mundo sabe que '-1' es todo' 1's. –

+0

'None' no debería ser' -1'?! – akhansari

Cuestiones relacionadas