有没有办法在C#中编写二进制文字,比如用0x前缀十六进制?0b不起作用.
如果没有,有什么简单的方法可以做到这一点?某种字符串转换?
C#7.0现在有二进制文字,这很棒.
[Flags] enum Days { None = 0, Sunday = 0b0000001, Monday = 0b0000010, // 2 Tuesday = 0b0000100, // 4 Wednesday = 0b0001000, // 8 Thursday = 0b0010000, // 16 Friday = 0b0100000, // etc. Saturday = 0b1000000, Weekend = Saturday | Sunday, Weekdays = Monday | Tuesday | Wednesday | Thursday | Friday }
由于该主题似乎已经转向在枚举中声明基于位的标志值,我认为值得为这类事情指出一个方便的技巧.左移运算符(<<
)允许您将位推到特定的二进制位置.将其与根据同一类中的其他值声明枚举值的能力相结合,并且您有一个非常容易阅读的位标记枚举声明性语法.
[Flags] enum Days { None = 0, Sunday = 1, Monday = 1 << 1, // 2 Tuesday = 1 << 2, // 4 Wednesday = 1 << 3, // 8 Thursday = 1 << 4, // 16 Friday = 1 << 5, // etc. Saturday = 1 << 6, Weekend = Saturday | Sunday, Weekdays = Monday | Tuesday | Wednesday | Thursday | Friday }
C#7.0支持二进制文字(以及通过下划线字符的可选数字分隔符).
一个例子:
int myValue = 0b0010_0110_0000_0011;
您还可以在Roslyn GitHub页面上找到更多信息.
只有整数和十六进制直接,我害怕(ECMA 334v4):
9.4.4.2整数文字整数文字用于写入int,uint,long和ulong类型的值.整数文字有两种可能的形式:十进制和十六进制.
要解析,您可以使用:
int i = Convert.ToInt32("01101101", 2);
添加到@ StriplingWarrior关于枚举中的位标志的答案,有一个简单的约定,您可以使用十六进制来向上计数位移.使用序列1-2-4-8,向左移动一列,然后重复.
[Flags] enum Scenery { Trees = 0x001, // 000000000001 Grass = 0x002, // 000000000010 Flowers = 0x004, // 000000000100 Cactus = 0x008, // 000000001000 Birds = 0x010, // 000000010000 Bushes = 0x020, // 000000100000 Shrubs = 0x040, // 000001000000 Trails = 0x080, // 000010000000 Ferns = 0x100, // 000100000000 Rocks = 0x200, // 001000000000 Animals = 0x400, // 010000000000 Moss = 0x800, // 100000000000 }
从右栏开始向下扫描并注意模式1-2-4-8(班次)1-2-4-8(班次)......
为了回答原来的问题,我第二次@ Sahuagin建议使用十六进制文字.如果你经常使用二进制数字来解决这个问题,那么获得十六进制的代价是值得的.
如果你需要在源代码中看到二进制数,我建议像上面的二进制文字一样添加注释.
您始终可以创建准文字,包含您所追求的值的常量:
const int b001 = 1; const int b010 = 2; const int b011 = 3; // etc ... Debug.Assert((b001 | b010) == b011);
如果经常使用它们,那么可以将它们包装在静态类中以便重复使用.
但是,如果您有任何与位相关的语义(在编译时已知),我会建议使用枚举:
enum Flags { First = 0, Second = 1, Third = 2, SecondAndThird = 3 } // later ... Debug.Assert((Flags.Second | Flags.Third) == Flags.SecondAndThird);
如果您查看.NET编译器平台("Roslyn")的语言功能实现状态,您可以清楚地看到在C#6.0中这是一个计划的功能,因此在下一个版本中我们可以按照常规方式执行.