How do you pass multiple enum values in C#?

C#Enums

C# Problem Overview


Sometimes when reading others' C# code I see a method that will accept multiple enum values in a single parameter. I always thought it was kind of neat, but never looked into it.

Well, now I think I may have a need for it, but don't know how to

  1. set up the method signature to accept this
  2. work with the values in the method
  3. define the enum

to achieve this sort of thing.


In my particular situation, I would like to use the System.DayOfWeek, which is defined as:

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

I want to be able to pass one or more of the DayOfWeek values to my method. Will I be able to use this particular enum as it is? How do I do the 3 things listed above?

C# Solutions


Solution 1 - C#

When you define the enum, just attribute it with [Flags], set values to powers of two, and it will work this way.

Nothing else changes, other than passing multiple values into a function.

For example:

[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);
}

For more details, see MSDN's documentation on Enumeration Types.


Edit in response to additions to question.

You won't be able to use that enum as is, unless you wanted to do something like pass it as an array/collection/params array. That would let you pass multiple values. The flags syntax requires the Enum to be specified as flags (or to bastardize the language in a way that's its not designed).

Solution 2 - C#

I think the more elegant solution is to use 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);
	}

Solution 3 - C#

I second Reed's answer. However, when creating the enum, you must specify the values for each enum member so it makes a sort of bit field. For example:

[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.
}

Solution 4 - C#

> In my particular situation, I would > like to use the System.DayOfWeek

You can not use the System.DayOfWeek as a [Flags] enumeration because you have no control over it. If you wish to have a method that accepts multiple DayOfWeek then you will have to use the params keyword

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 );

Otherwise you can create your own [Flags] enumeration as outlined by numerous other responders and use bitwise comparisons.

Solution 5 - C#

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

You have to specify the numbers, and increment them like this because it is storing the values in a bitwise fashion.

Then just define your method to take this enum

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

and to call it do something like

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

To check if one of the enum values was included check them using bitwise operations like

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
  }
}

Solution 6 - C#

[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
}

Call the method in this format

MethodName(DaysOfWeek.Tuesday | DaysOfWeek.Thursday);

Implement a EnumToArray method to get the options passed

private static void AddEntryToList(DaysOfWeek days, DaysOfWeek match, List<string> dayList, string entryText) {
    if ((days& match) != 0) {
        dayList.Add(entryText);
    }
}

internal static string[] EnumToArray(DaysOfWeek days) {
    List<string> verbList = new List<string>();

    AddEntryToList(days, HttpVerbs.Sunday, dayList, "Sunday");
    AddEntryToList(days, HttpVerbs.Monday , dayList, "Monday ");
    ...

    return dayList.ToArray();
}

Solution 7 - C#

Mark your enum with the [Flags] attribute. Also ensure that all of your values are mutually exclusive (two values can't add up to equal another) like 1,2,4,8,16,32,64 in your case

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

When you have a method that accepts a DayOfWeek enum use the bitwise or operator (|) to use multiple members together. For example:

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

To check if the parameter contains a specific member, use the bitwise and operator (&) with the member you are checking for.

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

Solution 8 - C#

Reed Copsey is correct and I would add to the original post if I could, but I cant so I'll have to reply instead.

Its dangerous to just use [Flags] on any old enum. I believe you have to explicitly change the enum values to powers of two when using flags, to avoid clashes in the values. See the guidelines for FlagsAttribute and Enum.

Solution 9 - C#

With the help of the posted answers and these:

  1. FlagsAttribute Class (Look at the comparison of using and not using the [Flags] attribute)
  2. Enum Flags Attribute

I feel like I understand it pretty well.

Thanks.

Solution 10 - C#

Something of this nature should show what you are looking for:

[Flags]
public enum SomeName
{
    Name1,
    Name2
}

public class SomeClass()
{
    public void SomeMethod(SomeName enumInput)
    {
        ...
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRonnie OverbyView Question on Stackoverflow
Solution 1 - C#Reed CopseyView Answer on Stackoverflow
Solution 2 - C#TillitoView Answer on Stackoverflow
Solution 3 - C#JacobView Answer on Stackoverflow
Solution 4 - C#Robert PaulsonView Answer on Stackoverflow
Solution 5 - C#TetraneutronView Answer on Stackoverflow
Solution 6 - C#RonyView Answer on Stackoverflow
Solution 7 - C#statenjasonView Answer on Stackoverflow
Solution 8 - C#DanView Answer on Stackoverflow
Solution 9 - C#Ronnie OverbyView Answer on Stackoverflow
Solution 10 - C#Andrew SiemerView Answer on Stackoverflow