2011-03-21 25 views
6

Digamos que tengo una enumeración de esta manera:C# enumeración excluye

[Flags] 
public enum NotificationMethodType { 
    Email = 1, 
    Fax = 2, 
    Sms = 4 
} 

Y digamos que tengo una variable definida como:

NotificationMethodType types = (NotificationMethodType.Email | NotificationMethodType.Fax) 

¿Cómo puedo averiguar todos los valores NotificationMethodType que no están definidos en la variable "tipos"? En otras palabras:

NotificationMethodType notAssigned = NotificationMethodType <that are not> types 

Respuesta

14

Si la lista de tipos nunca cambia, usted puede hacer esto:

NotificationMethodType allTypes = NotificationMethodType.Email | 
    NotificationMethodType.Fax | 
    NotificationMethodType.Sms; 

NotificationMethodType notAssigned = allTypes & ~types; 

El ~ crea un valor inverso, invirtiendo todos los bits.

Una forma típica de definir tales enumeraciones a por lo menos mantener la definición de "ALLTYPES" locales para la enumeración sería incluir dos nuevos nombres en la enumeración:

[Flags] 
public enum NotificationMethodType { 
    None = 0, 
    Email = 1, 
    Fax = 2, 
    Sms = 4, 
    All = Email | Fax | Sms 
} 

Nota: Si vas la ruta de agregar el valor All a la enumeración, tenga en cuenta que si types estaba vacío, no obtendría una enumeración que imprimiría como "Correo electrónico, fax, SMS", sino más bien como "Todos".

Si no desea mantener manualmente la lista de allTypes, puede hacerlo utilizando el método Enum.GetValues:

NotificationMethodType allTypes = 0; 
foreach (NotificationMethodType type in Enum.GetValues(typeof(NotificationMethodType))) 
    allTypes |= type; 

o puede hacer lo mismo con LINQ:

NotificationMethodType allTypes = 
    Enum.GetValues(typeof(NotificationMethodType)) 
    .Cast<NotificationMethodType>() 
    .Aggregate ((current, value) => current | value); 

Esto construye el valor allType al ordenar todos los valores individuales de la enumeración.

3

Un simple XOR hará el truco ...

NotificationMethodType all = (NotificationMethodType.Email | NotificationMethodType.Fax | NotificationMethodType.Sms); 
    NotificationMethodType used = (NotificationMethodType.Email | NotificationMethodType.Fax); 
    NotificationMethodType unused = (all^used); 

Para hacer esto un poco más limpio, agregue el Todo valor a su definición de enumeración directa (valor ajustado a 7, obviamente). De esta manera, puede agregar cosas a la enumeración más tarde sin romper este código

+0

fwiw, XOR (los^operadores) y las respuestas "y no" de Lasse son matemáticamente la misma cosa. –

0
var notAssigned = Enum.GetValues(typeof(NotificationMethodType)) 
         .Cast<NotificationMethodType>() 
         .Where(x => !types.HasFlag(x)) 
         .Aggregate((a, x) => a | x); 
+0

waay menos eficiente que cualquiera de las 2 respuestas que usan operadores bit a bit –

+0

@Robert: No puedo negar que es menos eficiente, pero su idoneidad realmente depende de lo que necesite el OP. Su propia respuesta requiere un valor 'todo' por separado para mantenerse sincronizado con la enumeración principal, ¡una pesadilla de mantenimiento si esa enumeración cambia alguna vez! (Y eso es más un inconveniente, imo, que un supuesto problema de eficiencia que probablemente * nunca * notará en la mayoría de las situaciones. Obviamente soy menos libre y fácil con mi downvoting que tú). – LukeH

+0

estuvo de acuerdo, Todo debe definirse como parte de la enumeración –