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
}

问题在于,除了这些单独的定义之外,还定义了成对(甚至是组)位。例如,(LowBeep | MediumBeep) = HighBeep

假设我有一个字节值 47,我想找到它的字符串表示形式。我目前实现的方法涉及查找字节中设置的位数,然后遍历这些位并从枚举中附加字符串值。类似于以下内容:

for (int i = 0; i < bitsSet.Count; i++)
{
    answer += ((ConfigDataHolder.Config4)bitsSet[i]).GetStringValue() + ", ";
}

这在定义比特组时会产生问题。在上面提到的情况下, 47 将包含两者MediumBeepLowBeep因此字符串表示应该HighBeep代替MediumBeepLowBeep单独。

考虑到可能存在与设置单个位完全不同的位组,是否有更有效的方法来获取字节中设置的每个位的字符串表示形式?

谢谢瑞诗

4

2 回答 2

1

您可以使用位掩码。看看这里的小例子:

[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");
        }
    }
}

按位比较非常快,您可以将结果添加到字符串生成器。我没有在我的枚举声明中使用移位运算符,但它是一样的。

于 2013-07-17T16:38:56.903 回答
0

您也可以将它们组合起来。看这里 :

        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)
    {
// ...
    }
}
于 2013-07-17T17:45:24.063 回答