C# 将字节中的位解析为枚举
我正在开发一个dll,它解析我从家庭自动化模块获得的二进制数据 但是我需要一些关于我的代码的建议。C# 将字节中的位解析为枚举,c#,enums,binary,C#,Enums,Binary,我正在开发一个dll,它解析我从家庭自动化模块获得的二进制数据 但是我需要一些关于我的代码的建议。 所以我得到了一个包含一些字节的消息,在这种情况下,每个字节都表示一个特定的条件 在我目前的代码中,每个条件都是一个枚举,我将枚举放在一个数组中,并检查是否设置了相应的位 private void ParseZoneConditionFlag1(int Flag1) // Flag1 = Hex represenation of byte { Zone_Status_ZoneCondit
所以我得到了一个包含一些字节的消息,在这种情况下,每个字节都表示一个特定的条件 在我目前的代码中,每个条件都是一个枚举,我将枚举放在一个数组中,并检查是否设置了相应的位
private void ParseZoneConditionFlag1(int Flag1) // Flag1 = Hex represenation of byte
{
Zone_Status_ZoneConditionFlagEnum[] FlagArray = new Zone_Status_ZoneConditionFlagEnum[8];
FlagArray[0] = Zone_Status_ZoneConditionFlagEnum.Faulted;
FlagArray[1] = Zone_Status_ZoneConditionFlagEnum.Tampered;
FlagArray[2] = Zone_Status_ZoneConditionFlagEnum.Trouble;
FlagArray[3] = Zone_Status_ZoneConditionFlagEnum.Bypassed;
FlagArray[4] = Zone_Status_ZoneConditionFlagEnum.Inhibited;
FlagArray[5] = Zone_Status_ZoneConditionFlagEnum.Low_Battery;
FlagArray[6] = Zone_Status_ZoneConditionFlagEnum.Loss_Supervision;
FlagArray[7] = Zone_Status_ZoneConditionFlagEnum.Reserved;
base.CheckBitsSet(FlagArray, Flag1, ZoneConditionFlags_List);
}
private void ParseZoneConditionFlag2(int Flag2)
{
Zone_Status_ZoneConditionFlagEnum[] FlagArray = new Zone_Status_ZoneConditionFlagEnum[8];
FlagArray[0] = Zone_Status_ZoneConditionFlagEnum.Alarm_Memory;
FlagArray[1] = Zone_Status_ZoneConditionFlagEnum.Bypass_Memory;
FlagArray[2] = Zone_Status_ZoneConditionFlagEnum.Reserved;
FlagArray[3] = Zone_Status_ZoneConditionFlagEnum.Reserved;
FlagArray[4] = Zone_Status_ZoneConditionFlagEnum.Reserved;
FlagArray[5] = Zone_Status_ZoneConditionFlagEnum.Reserved;
FlagArray[6] = Zone_Status_ZoneConditionFlagEnum.Reserved;
FlagArray[7] = Zone_Status_ZoneConditionFlagEnum.Reserved;
base.CheckBitsSet(FlagArray, Flag2, ZoneConditionFlags_List);
}
方法是我检查实际的位
protected void CheckBitsSet<T>(T[] ConstantArray, int HexValue, List<T> DestinationList)
{
byte b = (byte) HexValue;
for (int i = 0; i < Mask.Length; i++)
{
if(IsBitSet(b, i))
{
DestinationList.Add(ConstantArray[i]);
}
}
}
public bool IsBitSet(byte b, int pos)
{
return (b & (1 << pos)) != 0;
}
protectedvoid CheckBitsSet(T[]ConstantArray,int-HexValue,List-DestinationList)
{
字节b=(字节)HexValue;
for(int i=0;i
[Flags]
public enum MyEnum
{
Value1 = 1,
Value2 = 2,
Value3 = 4,
Value5 = 8
}
(...)
void Func(int flag)
{
MyEnum @enum = (MyEnum)flag;
// Testing, whether a flag is set
if ((@enum & MyEnum.Value1) != 0) // sth
}
那就:
[Flags]
enum MyFlags : short
{
None = 0,
Faulted = 1 << 0,
Tampered = 1 << 1,
Trouble = 1 << 2,
Bypassed = 1 << 3,
Inhibited = 1 << 4,
LowBattery = 1 << 5,
LossOfSupervision = 1 << 6,
AlarmMemory = 1 << 8,
BypassMemory = 1 << 9
}
static bool IsSet(MyFlags value, MyFlags flag)
{
return ((value & flag) == flag);
}
当你谈论复合标志时,它变得很诡诈
bool memoryProblem = IsSet(value, MyFlags.AlarmMemory | MyFlags.BypassMemory);
因为你需要弄清楚你的意思是“是否设置了这些标志中的任何一个?”还是“是否设置了所有这些标志?”
归根结底是考验
return ((value & flag) == flag); // means "are all set"
return ((value & flag) != 0); // means "is any set"
阅读:
// this is just some garbage that I'm pretending is a message from
// your module; I'm assuming the byte numbers in the image are
// zero-based, so the two that we want are: \/\/\/ (the 6,3)
byte[] data = { 12, 63, 113, 0, 13, 123, 14, 6, 3, 14, 15 };
// and I'm assuming "byte 7" and "byte 8" (image) are zero-based;
// MyFlags uses byte 7 *first*, so it is little-endian; we can get that
// via:
short flagsRaw = (short)(data[7] | (data[8] << 8));
MyFlags flags = (MyFlags)flagsRaw;
// flags has value Tampered | Trouble | AlarmMemory | BypassMemory,
// which is what we expect for {6,3}
//这只是一些垃圾,我假装它是来自
//您的模块;我假设图像中的字节数是
//基于零,所以我们想要的两个是:\/\/\/(6,3)
字节[]数据={12,63,113,0,13,123,14,6,3,14,15};
//我假设“字节7”和“字节8”(图像)是零基的;
//MyFlags首先使用字节7*first*,所以它是小尾端;我们可以得到它
//通过:
short flagsRaw=(short)(数据[7]|(数据[8])为什么您的枚举不仅仅是一个[Flags]
enum的右位?什么是枚举定义中的双箭头?在您刚达到400k之前从未见过这种语法,恭喜!我想这个话题已经讨论过很多次了。@Ian left shift;1哇,谢谢您的解释。但是我不理解“并将值作为2字节的值读取。”(简而言之,注意endianness),然后向MyFlags投下“part。你能详细说明我应该如何获得值吗?谢谢!
// this is just some garbage that I'm pretending is a message from
// your module; I'm assuming the byte numbers in the image are
// zero-based, so the two that we want are: \/\/\/ (the 6,3)
byte[] data = { 12, 63, 113, 0, 13, 123, 14, 6, 3, 14, 15 };
// and I'm assuming "byte 7" and "byte 8" (image) are zero-based;
// MyFlags uses byte 7 *first*, so it is little-endian; we can get that
// via:
short flagsRaw = (short)(data[7] | (data[8] << 8));
MyFlags flags = (MyFlags)flagsRaw;
// flags has value Tampered | Trouble | AlarmMemory | BypassMemory,
// which is what we expect for {6,3}