Битовые флаги - Чего мне не хватает? - PullRequest
6 голосов
/ 21 августа 2010

простой код:

protected void Page_Load(object sender, EventArgs e)
{
    DateTime now = DateTime.UtcNow;

    lit.Text += "<br/>now.DayOfWeek: " + now.DayOfWeek.ToString();

    // weekdays (Saturday is not included)
    DayOfWeek runningDays = DayOfWeek.Monday | DayOfWeek.Tuesday | DayOfWeek.Wednesday | DayOfWeek.Thursday | DayOfWeek.Friday;

    lit.Text += "<br/>" + runningDays.HasFlag(now.DayOfWeek);
    lit.Text += "<br/>" + runningDays.HasAny(now.DayOfWeek);
    lit.Text += "<br/>" + ((runningDays & now.DayOfWeek) != 0);

    // weekend (Saturday is in a weekend)
    runningDays = DayOfWeek.Saturday | DayOfWeek.Sunday;

    lit.Text += "<br/>" + runningDays.HasFlag(now.DayOfWeek);
    lit.Text += "<br/>" + runningDays.HasAny(now.DayOfWeek);
    lit.Text += "<br/>" + ((runningDays & now.DayOfWeek) != 0);
}

Помощник:

public static bool HasExactly(this DayOfWeek x, DayOfWeek y) { return x == y; }
public static bool HasAny(this DayOfWeek x, DayOfWeek y) { return 0 != (x & y); }
public static bool HasAll(this DayOfWeek x, DayOfWeek y) { return y == (x & y); }

сегодняшний вывод (суббота)

now.DayOfWeek: Saturday
True
True
True
True
True
True 

Но вывод должен быть таким:

now.DayOfWeek: Saturday
False
False
False
True
True
True 

Что мне здесь не хватает?

Ответы [ 5 ]

12 голосов
/ 21 августа 2010

Дни недели не являются битовыми флагами.http://msdn.microsoft.com/en-us/library/system.datetime.dayofweek.aspx

Значение констант в перечислении DayOfWeek варьируется от DayOfWeek.Sunday до DayOfWeek.Saturday.При приведении к целому числу его значение колеблется от нуля (что указывает на DayOfWeek.Sunday) до шести (что указывает на DayOfWeek.Saturday).

7 голосов
/ 11 октября 2011

Я знаю, что это старый пост, но на всякий случай - аккуратный синтаксис для перечисления флагов:

[Flags]
public enum DaysOfWeek
{
    None = 1 << 0,
    Monday = 1 << 1,
    Tuesday = 1 << 2,
    Wednesday = 1 << 3,
    Thursday = 1 << 4,
    Friday = 1 << 5,
    Saturday = 1 << 6,
    Sunday = 1 << 7
}

Вам понадобится None, чтобы указать, что ничего не выбрано.Такое перечисление позволяет указывать несколько дней, например:

var selectedDays = DaysOfWeek.Tuesday | DaysOfWeek.Friday;

Надеюсь, комментарии не нужны.И для того, чтобы «декодировать» значение:

public bool IsDayOfWeekSelected(DaysOfWeek which, DaysOfWeek selection)
{
    return selection & which == which;
}

И это тогда позволяет нам позвонить:

var isTuesday = IsDayOfWeekSelected(DaysOfWeek.Tuesday, selectedDays); // => true
var isWednesday = IsDayOfWeekSelected(DaysOfWeek.Wednesday, selectedDays); // => false
var isFriday = IsDayOfWeekSelected(DaysOfWeek.Friday, selectedDays); // => true

Надеюсь, это кому-нибудь поможет.

2 голосов
/ 21 августа 2010

Вы можете создать собственное перечисление DayOfWeek, если вам нужно использовать его как флаги:

[Flags]
public enum MyDayOfWeek { Sunday = 1, Monday = 2, Tuesday = 4, ... , Saturday = 64 };
1 голос
/ 21 августа 2010

DayOfWeek имеет порядковые номера.

Используйте List<DayOfWeek>.

Перейти к определению:

// Summary:
//     Specifies the day of the week.
[Serializable]
[ComVisible(true)]
public enum DayOfWeek
{
    // Summary:
    //     Indicates Sunday.
    Sunday = 0,
    //
    // Summary:
    //     Indicates Monday.
    Monday = 1,
    //
    // Summary:
    //     Indicates Tuesday.
    Tuesday = 2,
    //
    // Summary:
    //     Indicates Wednesday.
    Wednesday = 3,
    //
    // Summary:
    //     Indicates Thursday.
    Thursday = 4,
    //
    // Summary:
    //     Indicates Friday.
    Friday = 5,
    //
    // Summary:
    //     Indicates Saturday.
    Saturday = 6,
}
0 голосов
/ 21 августа 2010

Перечисление DayOfWeek предназначено для представления одного дня недели, а не набора дней.

Вы не получите ошибку компилятора при использовании &, потому что перечисления являются целыми числами, но оператор не делает то, что вы ожидаете (если только вы не планируете события только на понедельник, вторник или четверг).

Если вам нужен битовый флаг, тогда объявите тип битового флага, как предложил Рэй.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...