C# 字节和位转换 - 这可以做得更好吗?
本文关键字:更好 字节 转换 | 更新日期: 2023-09-27 17:57:18
我正在构建要通过蓝牙通信的字节数组。这些字节部分由枚举类型构建,如下所示:
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 直接转换为字符将导致它评估为其枚举值,即 MyMotor = B = 十六进制 42。
由于各种原因,我无法更改我的列表,因此我选择了感觉像是两行代码非常黑客化的代码部分:
String motorchar = Convert.ToString(Convert.ToInt32(MyMotor)); // convert to temp var
command[5] = (byte)(motorchar[0]); // store hex value of var
它按照我想要的方式工作,即命令[5] = hex31
我想知道是否有更好的方法。我找到的所有文章都在讨论处理整个字节数组,而不是单个字节和字符。
chars[0] = (char)('0' + ((byte)myMotor & 0x0F));
chars[1] = (char)('0' + (((byte)myMotor & 0xF0) >> 4));
不过,这需要对十六进制进行更多调整。
如果其他应用需要字符串,请提供一个字符串。创建一个字符串数组来保存值(你知道),并使用枚举的 int 值作为该数组的索引。
除非我错过了什么,否则您的两行代码相当于只是调用;
BitConverter.ToString(MyMotor);
不?
如果您知道程序的值和 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.
};
这将是最灵活和最易于维护的。
为什么不使用:
//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"完全相同。
我不明白你是如何得到你在帖子中提到的十进制 1 == 十六进制 31 或十六进制 42。 字符"1"的 ASCII 等效值是十进制 49 或十六进制 31。