将年份枚举与日期时间月份进行比较

zra*_*zdn 1 c# datetime enumeration

我有枚举:

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,
}  
Run Code Online (Sandbox Code Playgroud)

和Datime.Now.Month.

例如,如果month的值为5,则等于"May",我如何与月枚举进行比较?这个例子不起作用:if(!monthsOfYear.Any(x => x.Code.Equals((MonthsOfTheYear)(1 <<(currentDateTime.Month - 1)))

Eri*_*ert 8

这是一个代表一个月的奇怪方式,但要做你想做的事并不难.

你所需要的运算符是左移位操作,<<.如果你想象一个数字作为一串比特,比方说

0000 0000 1111 0000  (240 in binary)
Run Code Online (Sandbox Code Playgroud)

那么位移操作符将它们​​向左或向右移动了一些位置; 左转一个就是

0000 0001 1110 0000  (480 in binary)
Run Code Online (Sandbox Code Playgroud)

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

int may = 5;
MonthsOfTheYear result = (MonthsOfTheYear)(1 << (may - 1));
Run Code Online (Sandbox Code Playgroud)

合理?

更新:

这段代码有什么问题?

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

其中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;
}
Run Code Online (Sandbox Code Playgroud)

确保您了解其工作原理.如果你有旗帜

0000 0011
Run Code Online (Sandbox Code Playgroud)

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

0000 0010
Run Code Online (Sandbox Code Playgroud)

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

0000 0010
Run Code Online (Sandbox Code Playgroud)

这不是零,所以必须设置标志.

现在你可以说:

bool result = IsFlagSet((int)monthsOfYear, currentDateTime.Month - 1);
Run Code Online (Sandbox Code Playgroud)

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

合理?

  • @Belogix答案还有更多要考虑的问题,而不仅仅是它是否有效.这种思维方式将导致您创建许多难以维护,难以理解或修改的无法维护的代码.除非有特别令人信服的理由,否则在此字段中使用语义正确且技术正确的代码是合适的. (2认同)