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位。如果它对您有效,您可以从最低位开始。你需要什么样的面具取决于你的具体情况。如果这是一种常见的情况,为什么不呢?在我以前的工作中,我需要为每一位设置一个掩码,以了解硬件设备的状态(找到卡、通电等),并且工作正常