VB.net 下 enum类型Flag attribute

本文介绍如何使用C#中的枚举类型结合FlagsAttribute来实现多个状态的组合使用。通过示例展示了如何定义带有Flags属性的枚举类型,并利用位运算符进行状态设置和检查。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

The other day, I was using the RegexOptions enum when creating a Regular Expression, and I thought it would be useful to dedicate a blog entry to using enumeration values as flags.

The following is a poor example, but it should be illustrative enough.

Imagine we have a Client class, and one of the Client properties is ClientState. The ClientState enum can be defined as follows:

public enum ClientStates
{
  Ordinary,
  HasDiscount,
  IsSupplier,
  IsBlackListed,
  IsOverdrawn
}

As you can see - these options could be combined in several ways. Rather then creating separate properties in the Client class, we could enable a bitwise combination of enumeration values by using the FlagsAttribute, when defining our enum type. See below.

[Flags]
public enum ClientStates
{
  Ordinary,
  HasDiscount,
  IsSupplier,
  IsBlackListed,
  IsOverdrawn
}


This means we can now use the bitwise OR operator to combine these enum values. For instance:

Client c = new Client();
c.ClientState = (ClientStates.HasDiscount|ClientStates.IsSupplier|ClientStates.IsOverdrawn);

By setting the FlagsAttribute, the values for each enum value now effectively become bitflag patterns that look as follows if you see them in binary form:

00000000  0
00000001  1
00000010  2
00000100  4
00001000  16
00010000  32
00100000  64
01000000  128


As you can see, this bit pattern in our enum values enables us to use the bitwise operator and combine enum values. It is plain to see that all enum values combined, using the bitwise OR, would result in
11111111.

So, how do we check what particular ClientState values have been set? The key is the bitwise AND operator. Let's take our existing Client object 'c'.

[Flags]
public enum ClientStates
{
  Ordinary,       // 0000
  HasDiscount,    // 0001
  IsSupplier,     // 0010
  IsBlackListed,  // 0100
  IsOverdrawn     // 1000
}

So for instance, if we want to check c.ClientState for ClientStates.HasDiscount we can use the following expression:

(c.ClientState & ClientStates.HasDiscount) == ClientStates.HasDiscount

Assuming that c.ClientState contains HasDiscount, IsSupplier and IsOverdrawn, the bit patterns would look like:

c.ClientState:                1011
ClientStates.HasDiscount:     0001
(Logical AND):                0001


So by AND’ing the bit value to check for with the combined bit pattern, we either get the same enum bit pattern value back, or we get a bit pattern which only contains zero’s.

Here’s a little helper method you can use to check for particular ClientStates enum flag values:

public static bool ContainsClientState(ClientStates combined, ClientStates checkagainst)

{

  return ((combined & checkagainst)==checkagainst);
}

 

 

 

Namespace MyEvent

    <Flags()> _
   Public Enum EventFlags
        OnEvent1 = 1
        OnEvent2 = 2
        OnEvent3 = 4
        OnEventAll = 8
    End Enum

End Namespace

 Module AppMain

        Sub main()
            Dim myPublisher As New MyPublisher
            Dim mySubscriber As New MySubscriber

            myPublisher.Subscribe(mySubscriber, EventFlags.OnEvent1 Or EventFlags.OnEvent2)

            myPublisher.FireEvent(EventFlags.OnEvent2)

            Dim frm As New System.Windows.Forms.OpenFileDialog


            Console.ReadKey()
        End Sub

    End Module

 

 Public Class MyPublisher

        Public Event Event1 As AsyncInvoke.EventInvokeHelper.GenericEventHandler(Of Object, EventArgs)
        Public Event Event2 As AsyncInvoke.EventInvokeHelper.GenericEventHandler(Of Object, EventArgs)
        Public Event Event3 As AsyncInvoke.EventInvokeHelper.GenericEventHandler(Of Object, EventArgs)

        Public Sub Subscribe(ByVal subscriber As IMySubscriber, ByVal eventType As EventFlags)
            If (eventType And EventFlags.OnEvent1) = EventFlags.OnEvent1 Then
                AddHandler Me.Event1, AddressOf subscriber.OnEvent1
            End If
            If (eventType And EventFlags.OnEvent2) = EventFlags.OnEvent2 Then
                AddHandler Me.Event2, AddressOf subscriber.OnEvent2
            End If
            If (eventType And EventFlags.OnEvent3) = EventFlags.OnEvent3 Then
                AddHandler Me.Event3, AddressOf subscriber.OnEvent3
            End If
        End Sub

        Public Sub FireEvent(ByVal eventType As EventFlags)
            If (eventType And EventFlags.OnEvent1) = EventFlags.OnEvent1 Then
                AsyncInvoke.EventInvokeHelper.FireSync(Event1Event, Me, EventArgs.Empty)
            End If
            If (eventType And EventFlags.OnEvent2) = EventFlags.OnEvent2 Then
                AsyncInvoke.EventInvokeHelper.FireSync(Event2Event, Me, EventArgs.Empty)
            End If
            If (eventType And EventFlags.OnEvent3) = EventFlags.OnEvent3 Then
                AsyncInvoke.EventInvokeHelper.FireSync(Event3Event, Me, EventArgs.Empty)
            End If
        End Sub

    End Class

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值