ПРИВЕТ там, я немного плохо знаком с программированием, большим количеством хобби. Я задаюсь вопросом, имеют ли следующая логика или техника собственное имя или термин. Мой текущий проект имеет 7 флажков, один в течение каждого дня недели. Мне было нужно легкое для сохранения, какие флажки были установлены.
Следующее является методом к сохраненному установленные флажки к единственному числу. Каждый флажок получает значение, которое является двойным от последнего флажка. Когда я хочу узнать, какие флажки устанавливаются, я работаю назад и вижу, сколько раз я могу разделить итоговое значение на значение флажка.
private int SetSelectedDays()
{
int selectedDays = 0;
selectedDays += (dayMon.Checked) ? 1 : 0;
selectedDays += (dayTue.Checked) ? 2 : 0;
selectedDays += (dayWed.Checked) ? 4 : 0;
selectedDays += (dayThu.Checked) ? 8 : 0;
selectedDays += (dayFri.Checked) ? 16 : 0;
selectedDays += (daySat.Checked) ? 32 : 0;
selectedDays += (daySun.Checked) ? 64 : 0;
return selectedDays;
}
private void SelectedDays(int n)
{
if ((n / 64 >= 1) & !(n / 64 >= 2))
{
n -= 64;
daySun.Checked = true;
}
if ((n / 32 >= 1) & !(n / 32 >= 2))
{
n -= 32;
daySat.Checked = true;
}
if ((n / 16 >= 1) & !(n / 16 >= 2))
{
n -= 16;
dayFri.Checked = true;
}
if ((n / 8 >= 1) & !(n / 8 >= 2))
{
n -= 8;
dayThu.Checked = true;
}
if ((n / 4 >= 1) & !(n / 4 >= 2))
{
n -= 4;
dayWed.Checked = true;
}
if ((n / 2 >= 1) & !(n / 2 >= 2))
{
n -= 2;
dayTue.Checked = true;
}
if ((n / 1 >= 1) & !(n / 1 >= 2))
{
n -= 1;
dayMon.Checked = true;
}
if (n > 0)
{
//log event
}
}
Метод работает хорошо на то, что мне нужен он для, однако, если бы Вы действительно видите другой способ сделать это или лучший путь к записи, я интересовался бы Вашими предложениями.
Это напоминает битмаскинг. Когда я смогу найти блог, который я читал на этой неделе, используя именно этот пример, я опубликую его!
А, понял! Вот он.
Затем вы можете делать такие вещи, как:
DaysOfWeek week = DaysOfWeek.Sunday | DaysOfWeek.Monday;
выбрать воскресенье и понедельник. Или в вашем примере, когда вы проверяете значение каждого чекбокса, вы можете сделать:
DaysOfWeek week = DaysOfWeek.None; // DaysOfWeek.None = 0
if (Monday.Checked)
{
week |= DaysOfWeek.Monday;
}
и проверить, установлен ли определенный день:
DaysOfWeek week = DaysOfWeek.Monday | DaysOfWeek.Tuesday;
// this will be FALSE (so Wednesday will remain unchecked) because "week" contains Monday/Tuesday, but not Wednesday.
if ((week & DaysOfWeek.Wednesday) == DaysOfWeek.Wednesday)
{
Wednesday.Checked = true;
}
EDIT:
.NET встроенный DayOfWeek не позволяет использовать битовую маску для нескольких значений, поэтому вам придется создать свой собственный DaysOfWeek
enum.
Кто-то еще упоминал о маскировке битов, но я решил показать вам способ упростить код.
daySun.Checked = (n & 64) == 64;
daySat.Checked = (n & 32) == 32;
dayFri.Checked = (n & 16) == 16;
dayThu.Checked = (n & 8) == 8;
dayWed.Checked = (n & 4) == 4;
dayTue.Checked = (n & 2) == 2;
dayMon.Checked = (n & 1) == 1;
Вы можете создать перечисление со всеми днями и пометить его атрибутом [Flags], а затем присвоить каждому дню то же значение, что и ваше (bla.checked)? XX ..
, тогда вы можете использовать + =, и, или, чтобы получить ту же функциональность ..
поэтому, чтобы проверить, содержит ли значение, скажем, понедельник, вы должны сделать
if (myEnum & Days.Monday = = Days.Monday) { ... }
вы можете использовать перечисление ... его более читабельное и красивое
public enum daysOfWeek
{
Mon = 1, Tue = 2, Wed = 4, Thu = 8, Fri = 16, Sat = 32, Sun = 64
}
Это называется битовой маской, и вы можете сделать то же самое проще, используя Enum с атрибутом Flags .
вы можете скрыть сложность функции: и лучше сдвигать бит, а не делить
private bool get_bit(int val, int idx)
{
return ((val >> idx) & 1) != 0;
}
Это называется битовое поле, и да, это самый эффективный способ решения проблемы. Использование отдельных булевых значений, вероятно, будет использовать больше памяти, но IMO лучшая читаемость стоит шести байт или около того.