8

嗨,我对编程有点陌生,更多的是一种爱好。我想知道以下逻辑或技术是否具有特定名称或术语。我当前的项目有 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
     }
}

该方法适用于我需要它,但是,如果您确实看到了另一种方法或更好的写作方法,我会对您的建议感兴趣。

4

7 回答 7

6

其他人提到了位掩码,但我想我会向您展示一种简化代码的方法。

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;
于 2010-03-19T15:09:10.050 回答
4

这类似于位掩码。当我可以找到我本周使用这个确切示例阅读的博客时,我会发布它!

啊明白了! 在这里

然后,您可以执行以下操作:

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

编辑:

.NET 的内置 DayOfWeek 不允许对多个值进行位掩码,因此您需要滚动自己的DaysOfWeek枚举。

于 2010-03-19T15:06:46.003 回答
3

您可以创建一个包含所有日期的枚举并使用属性 [Flags] 对其进行标记,然后为每一天赋予与您的 (bla.checked) 相同的值?XX..

那么你可以使用 +=, and, or 来获得相同的功能..

所以要检查一个值是否包含让我们说星期一你会做

if (myEnum & Days.Monday == Days.Monday) { ... }

于 2010-03-19T15:08:32.313 回答
1

它被称为位掩码,您可以使用带有 Flags 属性的 Enum更轻松地做同样的事情。

于 2010-03-19T15:08:24.680 回答
1

它被称为位域,是的,它是解决这个问题的最节省空间的方法。使用单独的布尔值可能会使用更多内存,但 IMO 更好的可读性值得六个字节左右。

于 2010-03-19T15:09:44.850 回答
0

你可以使用一个枚举...它更具可读性和漂亮

    public enum daysOfWeek
    {
        Mon = 1, Tue = 2, Wed = 4, Thu = 8, Fri = 16, Sat = 32, Sun = 64
    }
于 2010-03-19T15:12:15.670 回答
0

您可以隐藏函数中的复杂性:最好是移位而不是除法

private bool get_bit(int val, int idx)
{
  return ((val >> idx) & 1) != 0;
}
于 2010-03-19T15:12:40.260 回答