C#二进制文字

tox*_*erd 174 c# syntax binary

有没有办法在C#中编写二进制文字,比如用0x前缀十六进制?0b不起作用.

如果没有,有什么简单的方法可以做到这一点?某种字符串转换?

Str*_*ior 164

更新

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

原帖

由于该主题似乎已经转向在枚举中声明基于位的标志值,我认为值得为这类事情指出一个方便的技巧.左移运算符(<<)允许您将位推到特定的二进制位置.将其与根据同一类中的其他值声明枚举值的能力相结合,并且您有一个非常容易阅读的位标记枚举声明性语法.

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

  • @ColeJohnson:许多开发人员都喜欢这样.我不像一些开发人员那样善于转换十六进制,有时最好迎合最低的共同点. (25认同)
  • @MikeT:您能否详细说明(或提供详细阐述的链接)?我经常声明以"1"开头的枚举,因为我希望能够[检测并快速失败](http://stackoverflow.com/a/6413841/120955),当一个值从未被初始化时.但是在某些情况下,默认值实际上是有意义的,我认为为该值添加名称没有任何问题. (5认同)
  • 我认为这是最有效的方式,因为枚举是作为常量构建的.使用可选的[Flags]属性,它们可以用于按位运算(与问题没有直接关系,但在描述二进制文字时特别有用).另一个有趣的可能性是将枚举类型强制为内置类型(在此示例中,在'Days'之后添加':byte'); 请参阅http://bit.ly/MKv42E中的内置类型 (2认同)
  • @MikeT来自[ca1008](https://docs.microsoft.com/en-us/visualstudio/code-quality/ca1008-enums-should-have-zero-value?view=vs-2017):**"如果应用了FlagsAttribute的枚举定义了一个零值成员,它的名称应为'None',表示枚举中没有设置任何值."**因此将它添加为默认值是完全有效的,_if_它被称为"无".总的来说,如果默认初始化字段中的值实际上有一个要显示的名称,它对我来说似乎更干净. (2认同)

BTo*_*TKD 128

C#7.0支持二进制文字(以及通过下划线字符的可选数字分隔符).

一个例子:

int myValue = 0b0010_0110_0000_0011;
Run Code Online (Sandbox Code Playgroud)

您还可以在Roslyn GitHub页面上找到更多信息.

  • 甜!在VS2017/C#7中工作得很好. (9认同)
  • @Dai 这与十六进制文字没有什么不同。换句话说,所有常量都是大端字节序,但在 Intel/AMD 和大多数 ARM 上存储为小端字节序。`0xDEADBEEF` 将存储为 `0xEF 0xBE 0xAD 0xDE` (4认同)
  • @ D.Singh我现在在C#7列表中看到它.https://github.com/dotnet/roslyn/issues/2136 (3认同)
  • 记住 C# 的二进制文字是大端字节序,但在 x86 上整数是小端字节序,因此 `Int16 = 0b0010_0110_0000_0011` 将存储为 `{ 0b0000_0011, 0b0010_0110 }` - 令人困惑。 (3认同)

Mar*_*ell 115

只有整数和十六进制直接,我害怕(ECMA 334v4):

9.4.4.2整数文字整数文字用于写入int,uint,long和ulong类型的值.整数文字有两种可能的形式:十进制和十六进制.

要解析,您可以使用:

int i = Convert.ToInt32("01101101", 2);
Run Code Online (Sandbox Code Playgroud)

  • 作为这个答案的更新,使用最新的尖端现代信息(2014年7月); C#6.0引入了二进制文字.看到我最新的答案wayyyyyy在底部... (4认同)
  • @BTownTKD 你的答案实际上是最重要的 :) 因为它是公认的答案。 (2认同)

Roy*_*ker 25

添加到@ 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
}
Run Code Online (Sandbox Code Playgroud)

从右栏开始向下扫描并注意模式1-2-4-8(班次)1-2-4-8(班次)......


为了回答原来的问题,我第二次@ Sahuagin建议使用十六进制文字.如果你经常使用二进制数字来解决这个问题,那么获得十六进制的代价是值得的.

如果你需要在源代码中看到二进制数,我建议像上面的二进制文字一样添加注释.


Mar*_*son 22

您始终可以创建准文字,包含您所追求的值的常量:

const int b001 = 1;
const int b010 = 2;
const int b011 = 3;
// etc ...
Debug.Assert((b001 | b010) == b011);
Run Code Online (Sandbox Code Playgroud)

如果经常使用它们,那么可以将它们包装在静态类中以便重复使用.

但是,如果您有任何与位相关的语义(在编译时已知),我会建议使用枚举:

enum Flags
{ 
    First = 0,
    Second = 1,
    Third = 2,
    SecondAndThird = 3
}
// later ...
Debug.Assert((Flags.Second | Flags.Third) == Flags.SecondAndThird);
Run Code Online (Sandbox Code Playgroud)


tot*_*dli 18

如果您查看.NET编译器平台("Roslyn")的语言功能实现状态,您可以清楚地看到在C#6.0中这是一个计划的功能,因此在下一个版本中我们可以按照常规方式执行.

二进制文字状态

  • @ColonelPanic - [Danation](http://stackoverflow.com/users/1192877/danation)指出它现在"在C#7列表中" - https://github.com/dotnet/roslyn/issues/2136 (4认同)
  • 它成功了吗?并非所有已发布博客的功能实际上都是Visual Studio 2015发布的. (2认同)