4

以下の簡単な例に注意してください。

Module Module1
    <Flags>
    Public Enum Names
        None    = 0
        Test    = 1
        Test2   = 2
        Test3   = 4
        Test4   = 8
    End Enum

    Sub Main()
        Dim test As Names = Names.Test Or Names.Test3
        If (test And Names.Test3) = Names.Test3
            Console.WriteLine("TRUE")
        Else
            Console.WriteLine("FALSE")
        End If
    End Sub
End Module

私の質問の最初の部分は、行に関連していますIf (test And Names.Test3) = Names.Test3

If test And Names.Test3フラグが存在するかのように単純にチェックしたほうがよいのではないでしょうか? ゼロ以外の値 (フラグが存在することを意味する) と評価された場合、条件の結果はTrueいずれにせよなります。

2 番目の方法をチェックする最初の方法を使用する正当な理由はありますか? (私の答えは VB.NET に対するものですが、これが他の場所、つまり C#、C++ などの潜在的な落とし穴であるかどうかも知りたいと思います)。

また、フラグの削除に関しては、これを行うには 2 つの方法があるようです。

test = test Xor Names.Test3test = test And Not Names.Test3

ただし、1 つ目は、フラグがない場合は追加し、ある場合は削除しますが、2 つ目はフラグを削除するだけです。それが唯一の違いですか?または、ある方法を他の方法よりも優先する必要がある別の理由がありますか?

4

2 に答える 2

5

これを効果的に置き換えることができると述べているのは正しいです:

If (test And Names.Test3) = Names.Test3 Then

これとともに

If (test And Names.Test3) Then

ただしOption Strict On、2 番目の例は、正しくエラーが発生するため、コンパイルされません。

Option Strict On disallows implicit conversions from 'Names' to 'Boolean'したがって、これをコンパイルするには、それをラップする必要がありますCBool

したがって、結論として、意図が非常に明確であるため、最初の例を使用する方がはるかに優れていると言えます。ビットが設定されているかどうかを確認しています。

フラグの削除、つまりビットの設定解除に関しては、次を使用する必要があります。

test = test And Not Names.Test3

を使用すると、値を切り替えるXor効果があります。

以下が役立つ場合があります(特に拡張メソッドを作成する場合):

Public Function SetBit(ByVal aValue As Names, ByVal aBit As Names) As Names
    Return (aValue Or aBit)
End Function

Public Function ClearBit(ByVal aValue As Names, ByVal aBit As Names) As Names
    Return (aValue And Not aBit)
End Function

Public Function IsBitSet(ByVal aValue As Names, ByVal aBit As Names) As Boolean
    Return ((aValue And aBit) = aBit)
End Function

Public Function ToggleBit(ByVal aValue As Names, ByVal aBit As Names) As Names
    Return (aValue Xor aBit)
End Function
于 2016-07-05T11:06:32.080 に答える
2

Flags列挙型は、すべてが純粋な単一ビット値である必要はないことに注意してください。たとえば、列挙型が次のように(より良い名前で)想像してみてください:

<Flags>
Public Enum Names
    None    = 0
    Test    = 1
    Test2   = 2
    Test3   = 4
    Test4   = 8
    Test2AndTest4 = 10
End Enum

test And Names.Test2AndTest4ここで、正しい質問に答えないため、それがゼロ以外であることをテストしたくないでしょう。したがって、マスクのすべてのビットが設定されていることを確認するために、一般にAnd、マスクにアクセスしてマスク値を確認し、比較することをお勧めします。

于 2016-07-05T14:04:10.200 に答える