C#字节查找所有已设置/未设置位的字符串表示形式
抱歉,如果这是一个重复的问题,我尝试搜索,但找不到任何与我的问题相关的内容 我有一个字节值,其中的每一位(或一组位)都有意义。我有一个带有自定义属性的枚举来定义这些位,如下所示:C#字节查找所有已设置/未设置位的字符串表示形式,c#,enums,bit-manipulation,custom-attributes,C#,Enums,Bit Manipulation,Custom Attributes,抱歉,如果这是一个重复的问题,我尝试搜索,但找不到任何与我的问题相关的内容 我有一个字节值,其中的每一位(或一组位)都有意义。我有一个带有自定义属性的枚举来定义这些位,如下所示: [Flags] public enum Config4 { [StringValue("Enable good-read beep")] GoodReadBeep = 1 << 0, [StringValue("Low beeper volume")] LowBeep = 1
[Flags]
public enum Config4
{
[StringValue("Enable good-read beep")]
GoodReadBeep = 1 << 0,
[StringValue("Low beeper volume")]
LowBeep = 1 << 1,
[StringValue("Medium beeper volume")]
MediumBeep = 1 << 2,
[StringValue("Low beeper frequency")]
LowFrequency = 1 << 3,
[StringValue("Medium beeper frequency")]
MediumFrequency = 1 << 4,
[StringValue("Medium beeper duration")]
MediumDuration = 1 << 5,
[StringValue("Long beeper duration")]
LongDuration = 1 << 6,
[StringValue("Reserved")]
Reserved = 1 << 7
}
这在定义位组时会造成问题。在上述情况下,47将同时包含MediumBeep
和LowBeep
,因此字符串表示应该是HighBeep
,而不是MediumBeep
和LowBeep
是否有一种更有效的方法来获取字节中每个位集的字符串表示形式,考虑到可能存在表示与设置单个位完全不同的内容的位组
谢谢
Rishi您可以使用位掩码。请看下面的小示例:
[Flags]
public enum MySettings
{
SettingA=1,
SettingB=2,
SettingC=4,
SettingD=8
}
class Program
{
static void Main(string[] args)
{
byte mySettings1 = 7;
byte mySettings2 = 2;
Console.WriteLine("Analyse mySetting1");
AnalyseSettings(mySettings1);
Console.WriteLine("Analyse mySetting2");
AnalyseSettings(mySettings2);
Console.ReadKey();
}
private static void AnalyseSettings(byte mySettings)
{
byte maskA = 1;
byte maskB = 2;
byte maskC = 4;
byte maskD = 8;
// Compare with bitwise and
if ((mySettings & maskA) == maskA)
{
Console.WriteLine("A Selected");
}
if ((mySettings & maskB) == maskB)
{
Console.WriteLine("B Selected");
}
if ((mySettings & maskC) == maskC)
{
Console.WriteLine("C Selected");
}
if ((mySettings & maskD) == maskD)
{
Console.WriteLine("D Selected");
}
}
}
按位比较非常快,您可以将结果添加到字符串生成器中。
我在枚举声明中不使用shift运算符,但它是相同的。您可以使用位掩码。请看下面的小示例:
[Flags]
public enum MySettings
{
SettingA=1,
SettingB=2,
SettingC=4,
SettingD=8
}
class Program
{
static void Main(string[] args)
{
byte mySettings1 = 7;
byte mySettings2 = 2;
Console.WriteLine("Analyse mySetting1");
AnalyseSettings(mySettings1);
Console.WriteLine("Analyse mySetting2");
AnalyseSettings(mySettings2);
Console.ReadKey();
}
private static void AnalyseSettings(byte mySettings)
{
byte maskA = 1;
byte maskB = 2;
byte maskC = 4;
byte maskD = 8;
// Compare with bitwise and
if ((mySettings & maskA) == maskA)
{
Console.WriteLine("A Selected");
}
if ((mySettings & maskB) == maskB)
{
Console.WriteLine("B Selected");
}
if ((mySettings & maskC) == maskC)
{
Console.WriteLine("C Selected");
}
if ((mySettings & maskD) == maskD)
{
Console.WriteLine("D Selected");
}
}
}
按位比较非常快,您可以将结果添加到字符串生成器中。
我在枚举声明中不使用shift运算符,但它是相同的。您也可以将它们组合起来。请看这里:
byte maskAndB = 3;
if ((mySettings & maskAndB) == maskAndB)
{
Console.WriteLine(" A and B selected");
}
这就像是数字的二进制表示。11=3,101=5
我想知道你为什么要用换档操纵器?您还使用了左移位,从数据类型的最高位开始
您还可以将枚举转换为int,然后再次执行检查:
[Flags]
public enum MySettings
{
SettingA=1,
SettingB=2,
SettingC=4,
SettingD=8
}
class Program
{
static void Main(string[] args)
{
var settingsFlags1 = MySettings.SettingA | MySettings.SettingB;
var settingsFlags2 = MySettings.SettingB | MySettings.SettingC | MySettings.SettingD;
int mySettings1 = (int)settingsFlags1;
int mySettings2 = (int)settingsFlags2;
Console.WriteLine("Analyse mySetting1");
AnalyseSettings(mySettings1);
Console.WriteLine("Analyse mySetting2");
AnalyseSettings(mySettings2);
Console.ReadKey();
}
private static void AnalyseSettings(int mySettings)
{
// ...
}
}
你也可以把它们结合起来。请看这里:
byte maskAndB = 3;
if ((mySettings & maskAndB) == maskAndB)
{
Console.WriteLine(" A and B selected");
}
这就像是数字的二进制表示。11=3,101=5
我想知道你为什么要用换档操纵器?您还使用了左移位,从数据类型的最高位开始
您还可以将枚举转换为int,然后再次执行检查:
[Flags]
public enum MySettings
{
SettingA=1,
SettingB=2,
SettingC=4,
SettingD=8
}
class Program
{
static void Main(string[] args)
{
var settingsFlags1 = MySettings.SettingA | MySettings.SettingB;
var settingsFlags2 = MySettings.SettingB | MySettings.SettingC | MySettings.SettingD;
int mySettings1 = (int)settingsFlags1;
int mySettings2 = (int)settingsFlags2;
Console.WriteLine("Analyse mySetting1");
AnalyseSettings(mySettings1);
Console.WriteLine("Analyse mySetting2");
AnalyseSettings(mySettings2);
Console.ReadKey();
}
private static void AnalyseSettings(int mySettings)
{
// ...
}
}
当然是
(LowBeep | MediumBeep)=HighBeep
?否则,HighBeep
将为零。它肯定是(LowBeep | MediumBeep)=HighBeep
?否则,HighBeep
将为零。我想过这样做,但如果有多个位组成一个设置,掩码会是什么?在我的示例中,“HighBeep”的字节掩码是什么?此外,在这个代码片段中,我似乎无法确定您在哪里使用枚举。它本质上是发送一个字节并将其与本地掩码变量进行比较,对吗?如果我尝试用枚举值执行“If”语句,我会得到一个编译器错误,基本上告诉我我不能执行,还有一个字节和一个枚举值。很抱歉延迟。您可以将bitflag枚举转换为int。请参阅下面更新的源代码。我曾想过这样做,但如果有多个位组成一个设置,掩码会是什么?在我的示例中,“HighBeep”的字节掩码是什么?此外,在这个代码片段中,我似乎无法确定您在哪里使用枚举。它本质上是发送一个字节并将其与本地掩码变量进行比较,对吗?如果我尝试用枚举值执行“If”语句,我会得到一个编译器错误,基本上告诉我我不能执行,还有一个字节和一个枚举值。很抱歉延迟。您可以将bitflag枚举转换为int。请参阅下面更新的源代码。确定。这意味着我必须为每种可能的组合准备一个面具,对吗?并且没有特别的理由使用换档操纵器。它使我更容易阅读,您可以查看偏移量,并知道哪个位映射到该枚举值。不需要计算它是否是第8位的第7位。如果它对您有效,您可以从最低位开始。你需要什么样的面具取决于你的具体情况。如果这是一种常见的情况,为什么不呢?在我以前的工作中,我需要为每一位设置一个掩码,以了解我们硬件设备的状态(找到卡、通电等),并且工作正常。这意味着我必须为每种可能的组合准备一个面具,对吗?并且没有特别的理由使用换档操纵器。它使我更容易阅读,您可以查看偏移量,并知道哪个位映射到该枚举值。不需要计算它是否是第8位的第7位。如果它对您有效,您可以从最低位开始。你需要什么样的面具取决于你的具体情况。如果这是一种常见的情况,为什么不呢?在我以前的工作中,我需要为每一位设置一个掩码,以了解硬件设备的状态(找到卡、通电等),并且工作正常