简体   繁体   中英

List of Enums C#

Am using an api where I need to set a list of days in a week, there is a enum for these days but I cannot use List. The parameter is expecting something like this RecurringDay.Monday | RecurringDay.Wednesday

I cannot seem to find a means of building this up with the values I have for my days without doing it in a way that seems very poor coding. How can I construct a list of days a user selects like RecurringDay.Monday | RecurringDay.Wednesday | RecurringDay.Friday

[Flags]
public enum RecurringDay
{
    RecurringNone = 0,
    RecurringSunday = 1,
    RecurringSaturday = 2,
    RecurringWeekend = 3,
    RecurringFriday = 4,
    RecurringThursday = 8,
    RecurringWednesday = 16,
    RecurringTuesday = 32,
    RecurringMonday = 64,
    RecurringWeekdays = 124,
    RecurringAlldays = 127
}

schedule.LocalTime = new HueDateTime()
{
  DateTime = DateTime.Now.AddMinutes(1),
  RecurringDay = RecurringDay.RecurringMonday | RecurringDay.RecurringAlldays
};

Flags enums are bit vectors. Each enum value corresponds to a bit in the underlying integer. Combinations of set bits represents combinations of values. For this to work every value need to be a power of 2, ie exactly on bit is set. But combinations of bits may also have names, like RecurringWeekend in the above example.

Example:

0b00010001 = 0x11 = 17
         1 Sunday included
        0  Saturday not included
       0   Friday not included
      0    Thursday not included
     1     Wednesday included
    0      Tuesday not included
   0       Monday not included

To build up such a combination just use the |= operator:

RecurringDay days = RecurringDay.RecurringNone;
if (user_selected_Sunday)
  days |= RecurringDay.RecurringSunday;
if (user_selected_Saturday)
  days |= RecurringDay.RecurringSaturday;
...
if (user_selected_Monday)
  days |= RecurringDay.RecurringMonday;

At the end day will contain the appropriate combination of days matching the users selection.

In fact every instance of a flags enum value is already a set of values which of course might also be empty, ie RecurringDay.RecurringNone . No need to use List<> here.

I'm not sure what your question is, but this code looks fine to me. First, I got rid of your recurring "Recurring", and made the combinations more clear (as @Heretic Monkey suggested):

[Flags]
public enum RecurringDay
{
    None = 0,
    Sunday = 1,
    Saturday = 2,
    Friday = 4,
    Thursday = 8,
    Wednesday = 16,
    Tuesday = 32,
    Monday = 64,
    Weekends = Saturday | Sunday,
    Weekdays = Monday | Tuesday | Wednesday | Thursday | Friday,
    Alldays = Weekdays | Weekends,
}

Then I recreated your HueDateTime class with property names that weren't type names (for clarity):

public class HueDateTime
{
    public DateTime When { get; set; }
    public RecurringDay HowOften { get; set; }
}

Then I consumed the code:

var schedule = new HueDateTime()
{
    When = DateTime.Now + TimeSpan.FromHours(1),
    HowOften = RecurringDay.Monday | RecurringDay.Wednesday
};

var succeeded = Enum.TryParse<RecurringDay>("Sunday,Monday,Tuesday", out var when);

When that last statement finishes executing, succeeded is true and when is typed as a RecurringDay with a value of Sunday | Tuesday | Monday Sunday | Tuesday | Monday Sunday | Tuesday | Monday . I'm pretty sure this code could easily pass a picky code reviewer.

I just noticed, your days go backwards (Sunday, Saturday ... Tuesday, Monday) - any particular reason? That's why when ends up as Sunday | Tuesday | Monday Sunday | Tuesday | Monday Sunday | Tuesday | Monday .

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM