【问题标题】:c# byte and bit casting - could this be done better?c# 字节和位转换 - 这可以做得更好吗?
【发布时间】:2011-08-31 10:31:24
【问题描述】:

我正在构建要通过蓝牙进行通信的字节数组。这些字节部分是由枚举类型构建的,例如:

public enum Motor
{
   A = 0x00,
   B = 0x01,
   C = 0x02,
   AB = 0x03,
   AC = 0x04,
   BC = 0x05,
}

稍后在我的代码中,我创建了一个名为 MyMotor 的变量,类型为 MyMotor.B。然后我将此变量传递给我构建字节数组的方法。

我的问题是我通过蓝牙与之通信的软件期望枚举值的十六进制值作为字符串,即 MyMotor.B = 字节 0x01 = dec 1 = 十六进制 31。但是将 MyMotor 直接转换为 char 会导致它评估它的枚举值,即 MyMotor = B = hex 42。

由于各种原因,我无法更改我的枚举列表,所以我决定将两行代码部分组合在一起:

String motorchar = Convert.ToString(Convert.ToInt32(MyMotor)); // convert to temp var
command[5] = (byte)(motorchar[0]); // store hex value of var

它可以按我的意愿工作,即 command[5] = hex31

我想知道是否有更好的方法。我发现的所有文章都在讨论处理整个字节数组而不是单个字节和字符。

【问题讨论】:

  • 您的枚举似乎包含一些基本值及其组合。这就是 [Flags] 的用途。
  • @svick: A | C 不给他AC
  • @Mehrdad,我假设他自己创建了枚举,而不关心实际值。
  • @svick:看起来他不能对我这样做......
  • @Mehrdad,啊,我没有阅读整个问题。好吧,我的评论在这里毫无意义。

标签: c# byte


【解决方案1】:
chars[0] = (char)('0' + ((byte)myMotor & 0x0F));
chars[1] = (char)('0' + (((byte)myMotor & 0xF0) >> 4));

不过,这需要对十六进制进行更多调整。

【讨论】:

    【解决方案2】:

    如果您的其他应用需要一个字符串,则提供一个。 创建一个字符串数组来保存值(你知道),并使用枚举的 int 值作为该数组的索引。

    【讨论】:

      【解决方案3】:

      除非我遗漏了什么,你的两行代码相当于只是调用;

      BitConverter.ToString(MyMotor);
      

      没有?

      【讨论】:

      • 没关系,我只是在VS中尝试过,看看你的问题是什么。 BitConverter 需要一个 byte[] ,因为您的枚举值中有一个字节。继续前进,这里没什么可看的。
      • Bitconverter 需要一个字节数组而不是单个字节
      【解决方案4】:

      如果您知道您的程序的值和 API 期望的值总是相差某个固定值(例如,AC = 0x04,但 API 想要“4”,那么您可以编写一个简单的转换:

      char c = (char)((int)Motor + '0');
      

      但是,当值超过 10 个时,这会变得有点难看。您可以将其特殊化为十六进制数字,但之后就很糟糕了。

      你最好创建一个查找表,最通用的是字典:

      Dictionary<Motor, string> MotorLookup = new Dictionary<Motor, string>() {
          { Motor.A, "0" },
          { Motor.B, "1" },
          // etc, etc.
      };
      

      这将是最灵活和最可维护的。

      【讨论】:

        【解决方案5】:

        为什么不使用:

        //If you want the ASCII representation.
        //  e.g. myMotor == B, then the Byte Decimal value will be 49 or 0x31.
        command[5] = (byte)((byte)myMotor).ToString()[0];
        

        //If you want the numeric representation:
        //  e.g. myMotor == B, then the Byte Decimal value will be 1 or 0x01.
        command[5] = (byte)myMotor;
        

        我看到您使用“0x01”和“0x05”之类的值。 “0x”前缀意味着它是一个十六进制数,但你永远不会超过 5,所以它与使用整数值“1”和“5”完全相同。

        我看不出你是如何得到你在帖子中提到的 Decimal 1 == Hex 31 或 Hex 42 的。 Char '1' 的 ASCII 等价物是十进制 49 或十六进制 31。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-09-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-12-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多