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
to achieve this sort of thing.
[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?
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).
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);
}
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.
}
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.
[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
}
}
[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();
}
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");
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 .
With the help of the posted answers and these:
I feel like I understand it pretty well.
Thanks.
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)
{
...
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.