从bitflag中提取特定值

时间:2015-04-08 04:49:35

标签: c# asp.net enums

我在MS SQL Server表中有一个列,用于存储几个可能值的按位数据。以下是它具有的值:

Basic = -1
Type A = 0x0001
Type B = 0x0002
Type C = 0x0004
Type D = 0x0008
Type E = 0x0016
Type F = 0x0032

我正在尝试使用这些值填充列表框。 “Basic”类型实际上有一个单独的位列,用于确定它是否为真,但我希望我创建的这个新列代表所有可用的值(我不能删除“Basic”的位列因为有一个依赖它的遗留系统。)

我对按位数据或如何操作它没有任何经验,所以除了我知道我需要遍历这个列返回的值,我完全迷失了。我已经看到enum应该用于这种事情,如下所示:

[Flags]
public enum Types
 {
        Basic = -1,
        Type A = 0x0001,
        Type B = 0x0002,
        Type C = 0x0004,
        Type D = 0x0008,
        Type E = 0x0016,
        Type F = 0x0032
}

但问题是我需要将其设置为动态,因此如果稍后使用新值Type G = 0x0064更新表,则不需要在代码中进行其他更改以使该值显示在列表框中。如何以一种不断寻找新值的方式使用枚举?

1 个答案:

答案 0 :(得分:0)

使用枚举的按位定义

枚举的默认类型是int(32位整数),它为您提供32位的位置。它就像你写过

一样
public enum Types : int { ... }

根据您需要的位数,您可以访问

  • 字节(8位无符号)
  • sbyte(8位签名)
  • 短(16位签名)
  • ushort(16位无符号)
  • int(32位签名)
  • uint(32位无符号)
  • long(64位签名)
  • ulong(64位无符号)

其中带符号的数字在2's complement中表示。所以,我不确定 Basic 应该表示什么位,但是如果你将值设置为-1,就像在你的例子中那样,等效的32位值是0xFFFFFFFF(所有一个&#) 39; S)。尝试将每个位位置用作标记意味着您已经转动了所有标记" on"。

您在分配标志值时也会出现轻微的数学错误,因为您已将十进制值一次性正确激活,但您已列出了值为十六进制,不会产生您正在寻找的效果。

十六进制列表很适合那些在位级工作的人,因为每个十六进制数代表4位。以下是具有十六进制值的枚举的更正版本:

public enum Types
{
    A = 0x0001,
    B = 0x0002,
    C = 0x0004,
    D = 0x0008,
    E = 0x0010,
    F = 0x0020,
    G = 0x0040
}

或者,如果您想使用十进制值编写等效值:

public enum Types
{
    A = 1,
    B = 2,
    C = 4,
    D = 8,
    E = 16,
    F = 32,
    G = 64
}

使用Flags属性的重要一点是,枚举中的每个值只能激活一个位的位置。声明二进制值here的一个有用技巧,我在下面使用你的枚举重新迭代了它。这清楚地标识了您尝试使用Flags属性捕获的内容,并使用位移运算符来标识您的枚举值。

public enum Types
{
    A = 1,
    B = 1 << 1,
    C = 1 << 2,
    D = 1 << 3,
    E = 1 << 4,
    F = 1 << 5,
    G = 1 << 6
}

在列表框中显示枚举值

最后,关于您尝试展示的内容。我只是假设您正在尝试使用WPF执行此操作。如果您正在使用其他方式生成用户界面,则必须进一步搜索。

我从这篇短文中借用并测试了这一点:Bind Enum to a WPF ListBox using ObjectDataProvider。您基本上使用ObjectDataProvider绑定到枚举,然后将结果绑定到列表框。我假设你已经在这个例子的名称空间WpfTest中定义了你的枚举。

<Window x:Class="WpfTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfTest"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ObjectDataProvider MethodName="GetValues" ObjectType="{x:Type sys:Enum}" x:Key="EnumValues">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="local:Types" />
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Window.Resources>

    <StackPanel>
        <ListBox DataContext="{Binding Source={StaticResource EnumValues}}" ItemsSource="{Binding}"/>
    </StackPanel>
</Window>

执行此操作后,列表框将始终显示您在“类型”中定义的所有枚举。