¿Cómo se pasan múltiples valores enum en C #?

A veces, al leer el código C # de otros, veo un método que aceptará múltiples valores enum en un solo parámetro. Siempre pensé que era algo ordenado, pero nunca lo analicé.

Bueno, ahora creo que puedo necesitarlo, pero no sé cómo

  1. configurar la firma del método para aceptar esto
  2. trabajar con los valores en el método
  3. definir la enumeración

para lograr este tipo de cosas


En mi situación particular, me gustaría usar el System.DayOfWeek, que se define como:

[Serializable] [ComVisible(true)] public enum DayOfWeek { Sunday = 0, Monday = 1, Tuesday = 2, Wednesday = 3, Thursday = 4, Friday = 5, Saturday = 6 } 

Quiero poder pasar uno o más de los valores de DayOfWeek a mi método. ¿Podré usar esta enumeración particular tal como es? ¿Cómo hago las 3 cosas enumeradas arriba?

Cuando defines la enumeración, simplemente la atribuyes con [Banderas], configura valores a potencias de dos, y funcionará de esta manera.

Nada más cambia, aparte de pasar múltiples valores en una función.

Por ejemplo:

 [Flags] enum DaysOfWeek { Sunday = 1, Monday = 2, Tuesday = 4, Wednesday = 8, Thursday = 16, Friday = 32, Saturday = 64 } public void RunOnDays(DaysOfWeek days) { bool isTuesdaySet = (days & DaysOfWeek.Tuesday) == DaysOfWeek.Tuesday; if (isTuesdaySet) //... // Do your work here.. } public void CallMethodWithTuesdayAndThursday() { this.RunOnDays(DaysOfWeek.Tuesday | DaysOfWeek.Thursday); } 

Para obtener más detalles, consulte la documentación de MSDN sobre tipos de enumeración .


Edite en respuesta a las adiciones a la pregunta.

No podrá usar esa enumeración como está, a menos que desee hacer algo así como pasarlo como una matriz de matriz / colección / params. Eso te permitiría pasar múltiples valores. La syntax de los indicadores requiere que Enum se especifique como indicadores (o para bastardear el idioma de una manera que no está diseñada).

Creo que la solución más elegante es usar HasFlag ():

  [Flags] public enum DaysOfWeek { Sunday = 1, Monday = 2, Tuesday = 4, Wednesday = 8, Thursday = 16, Friday = 32, Saturday = 64 } public void RunOnDays(DaysOfWeek days) { bool isTuesdaySet = days.HasFlag(DaysOfWeek.Tuesday); if (isTuesdaySet) { //... } } public void CallMethodWithTuesdayAndThursday() { RunOnDays(DaysOfWeek.Tuesday | DaysOfWeek.Thursday); } 

Respondo la respuesta de Reed. Sin embargo, al crear la enumeración, debe especificar los valores para cada miembro enum, por lo que constituye un campo de tipo de bit. Por ejemplo:

 [Flags] public enum DaysOfWeek { Sunday = 1, Monday = 2, Tuesday = 4, Wednesday = 8, Thursday = 16, Friday = 32, Saturday = 64, None = 0, All = Weekdays | Weekend, Weekdays = Monday | Tuesday | Wednesday | Thursday | Friday, Weekend = Sunday | Saturday, // etc. } 

En mi situación particular, me gustaría usar el System.DayOfWeek

No puede usar System.DayOfWeek como una enumeración [Flags] porque no tiene control sobre ella. Si desea tener un método que acepte varias DayOfWeek , deberá usar la palabra clave params

 void SetDays(params DayOfWeek[] daysToSet) { if (daysToSet == null || !daysToSet.Any()) throw new ArgumentNullException("daysToSet"); foreach (DayOfWeek day in daysToSet) { // if( day == DayOfWeek.Monday ) etc .... } } SetDays( DayOfWeek.Monday, DayOfWeek.Sunday ); 

De lo contrario, puede crear su propia enumeración [Flags] como se describe por muchos otros respondedores y utilizar comparaciones bit a bit.

 [Flags] public enum DaysOfWeek { Mon = 1, Tue = 2, Wed = 4, Thur = 8, Fri = 16, Sat = 32, Sun = 64 } 

Debe especificar los números e incrementarlos así porque está almacenando los valores en forma de bit.

Entonces simplemente define tu método para tomar esta enumeración

 public void DoSomething(DaysOfWeek day) { ... } 

y llamarlo hacer algo como

 DoSomething(DaysOfWeek.Mon | DaysOfWeek.Tue) // Both Monday and Tuesday 

Para verificar si se incluyó alguno de los valores enumerados, verifíquelos usando operaciones bit a bit como

 public void DoSomething(DaysOfWeek day) { if ((day & DaysOfWeek.Mon) == DaysOfWeek.Mon) // Does a bitwise and then compares it to Mondays enum value { // Monday was passed in } } 
 [Flags] public enum DaysOfWeek{ Sunday = 1 < < 0, Monday = 1 << 1, Tuesday = 1 << 2, Wednesday = 1 << 3, Thursday = 1 << 4, Friday = 1 << 5, Saturday = 1 << 6 } 

llamar al método en este formato

MethodName (DaysOfWeek.Tuesday | DaysOfWeek.Thursday);

Implementar un método EnumToArray para obtener las opciones pasadas

 private static void AddEntryToList(DaysOfWeek days, DaysOfWeek match, List dayList, string entryText) { if ((days& match) != 0) { dayList.Add(entryText); } } internal static string[] EnumToArray(DaysOfWeek days) { List verbList = new List(); AddEntryToList(days, HttpVerbs.Sunday, dayList, "Sunday"); AddEntryToList(days, HttpVerbs.Monday , dayList, "Monday "); ... return dayList.ToArray(); } 

Marque su enumeración con el atributo [Flags]. También asegúrese de que todos sus valores sean mutuamente excluyentes (dos valores no pueden sumrse a igual a otro) como 1,2,4,8,16,32,64 en su caso

 [Flags] public enum DayOfWeek { Sunday = 1, Monday = 2, Tuesday = 4, Wednesday = 8, Thursday = 16, Friday = 32, Saturday = 64 } 

Cuando tenga un método que acepte una enum de DayOfWeek, utilice el operador bit a bit (|) para usar múltiples miembros juntos. Por ejemplo:

 MyMethod(DayOfWeek.Sunday|DayOfWeek.Tuesday|DayOfWeek.Friday) 

Para verificar si el parámetro contiene un miembro específico, use el operador bit a bit (y) con el miembro que está buscando.

 if(arg & DayOfWeek.Sunday == DayOfWeek.Sunday) Console.WriteLine("Contains Sunday"); 

Reed Copsey es correcto y agregaría a la publicación original si pudiera, pero no puedo, así que tendré que responder en su lugar.

Es peligroso usar [Banderas] en cualquier enumeración antigua. Creo que tienes que cambiar explícitamente los valores enum a potencias de dos cuando uses banderas, para evitar conflictos en los valores. Vea las pautas para FlagsAttribute y Enum .

Algo de esta naturaleza debe mostrar lo que estás buscando:

 [Flags] public enum SomeName { Name1, Name2 } public class SomeClass() { public void SomeMethod(SomeName enumInput) { ... } } 

Con la ayuda de las respuestas publicadas y estas:

  1. Clase FlagsAttribute (Vea la comparación de usar y no usar el atributo [Flags])
  2. Enum Flags Attribute

Siento que lo entiendo bastante bien.

Gracias.