1

我有枚举:

public enum MonthsOfTheYear
{
    January = 1,
    February = 2,
    March = 4,
    April = 8,
    May = 16,
    June = 32,
    July = 64,
    August = 128,
    September = 256,
    October = 512,
    November = 1024,
    December = 2048,
    AllMonths = 4095,
}  

和 Datime.Now.Month。

例如,如果月份的值为 5,它等于“May”,我如何与月份枚举进行比较?此示例不起作用: if (!monthsOfYear.Any(x=>x.Code.Equals((MonthsOfTheYear)(1 << (currentDateTime.Month - 1)))

4

1 回答 1

8

这种表示一个月的方式有点奇怪,但做自己想做的事情并不难。

您需要的运算符是左位移运算符, <<。如果您将数字想象为一串位,请说

0000 0000 1111 0000  (240 in binary)

然后位移运算符将它们向左或向右移动一些位置;左移一个将是

0000 0001 1110 0000  (480 in binary)

在您的情况下,一月是第 1 位左移零次,二月是第 1 位左移一次,依此类推:

int may = 5;
MonthsOfTheYear result = (MonthsOfTheYear)(1 << (may - 1));

说得通?

更新:

这段代码有什么问题?

!monthsOfYear.Any(x=>x.Code.Equals((MonthsOfTheYear)(1 << (currentDateTime.Month - 1)))))

哪里 monthsOfYear 是 1 + 2 + 4 + 8 ?

您有数字 1 + 2 + 4 + 8,即 15。这不等于1、2、4 或 8。首先,您不希望相等。

要测试是否设置了标志,请使用&运算符。

让我们通过抽象成一个辅助方法来使这更容易理解:

// Is bit "flag" set in bit field "flags"?
static bool IsFlagSet(int flags, int flag)
{
    return (flags & (1 << flag)) != 0;
}

确保你了解它是如何工作的。如果你有旗帜

0000 0011

您询问是否设置了标志 1,然后它将位 1 向左移动 1 位:

0000 0010

然后说“如果两个相应的位都设置了,给我 1,否则为零。” 所以那是

0000 0010

那不是零,因此标志必须已设置。

现在你可以说:

bool result = IsFlagSet((int)monthsOfYear, currentDateTime.Month - 1);

如果设置了该标志,则为 true,否则为 false。

说得通?

于 2013-05-14T14:59:08.160 回答