3

以下に示すように、FlagsAttributeを適用して列挙型を評価しようとしています。問題は、適切なifステートメントが実行されることを保証するために取るとんでもない量のコードです。列挙型の特定の組み合わせが設定されている場合にのみ実行する必要がある4つのifステートメントがありますが、それ以外はありません

  1. プライベート、静的
  2. プライベート
  3. 特権
  4. 公衆

必要なフラグの存在を検出するのは簡単ですが、他のフラグが設定されていないことも確認する必要があります。これは、入力するコードの量がばかげており、メンテナンスの悪夢のように見えます。

[Flags]
public enum AccessModifierType : short
{
    Infer = 1,
    Public = 2,
    Privileged = 4,
    Private = 8,
    Static = 16
}

誰かがこれをもっと簡潔にするためにifステートメントを書き直すことができますか?

if ((Model.CurrentContext.CurrentAccessModifierType & AccessModifierType.Public) == AccessModifierType.Public
        && (Model.CurrentContext.CurrentAccessModifierType & AccessModifierType.Static) != AccessModifierType.Static
        && (Model.CurrentContext.CurrentAccessModifierType & AccessModifierType.Privileged) != AccessModifierType.Privileged
        && (Model.CurrentContext.CurrentAccessModifierType & AccessModifierType.Private) != AccessModifierType.Private){
}
4

4 に答える 4

2

最終的なサンプルが元の要件とどのように関連しているかは明確ではありませんが(特別な意味があると感じますか?)、特定のInferビットの組み合わせだけを探している場合は、正確な期待値に対して同等性テストを使用してみませんか?列挙値(ビット単位のORで組み立てられます)?

if(myUnknownFlagsEnumValue == (MyEnum.RequiredFlag1 | MyEnum.RequiredFlag2))
{
    ...
}
于 2012-05-01T08:25:51.913 に答える
1

まず、繰り返し使用している値を上げるのと同様に、0と比較する方が簡単です。

var access = Model.CurrentContext.CurrentAccessModifierType;
if ((access & AccessModifierType.Public) != 0
    && (access & AccessModifierType.Static) == 0
    && (access & AccessModifierType.Privileged) == 0
    && (access & AccessModifierType.Private) == 0)
{
    ...
}

テストしたいが他のフラグがない場合は、次のようにします。

if (Model.CurrentContext.CurrentAccessModifierType == AccessModifierType.Public)
{
    ...
}

公開したいが、他の3つは公開したくない場合は、その後、おそらく:

if(Model.CurrentContext.CurrentAccessModifierType & (
     AccessModifierType.Public | AccessModifierType.Static |
     AccessModifierType.Priveleged | AccessModifierType.Private
    ) ==  AccessModifierType.Public)
{
   ...
}

これには、テストが1つしかないという利点があります(ビルド中にコンパイラーが実行することも期待される|ため、これは「、、」または「、、」ldcにすぎません。andbrtrueldcandbrfalse

于 2012-05-01T08:23:45.123 に答える
0

フラグが1つだけ設定されているかどうかをテストするには、そのフラグに対してテストするだけです。

if( Model.CurrentContext.CurrentAccessModifierType == AccessModifierType.Private)
...

フラグの正確な組み合わせと等しいかどうかを確認するには、もう一度、その組み合わせに対してテストします。

if( Model.CurrentContext.CurrentAccessModifierType == (AccessModifierType.Private & AccessModifierType.Static))
...

これを回避するには、列挙型は実際には単なる数値であることを忘れないでください。したがって、列挙型の値がPrivateの場合は、8として格納されるだけなので、8(またはPrivate)に等しいかどうかをテストします。プライベートで静的の場合は8+16 = 24です。したがって、両方であるかどうかをテストするには、24(またはプライベートと静的)に等しいかどうかをテストします。

于 2012-05-01T08:35:47.533 に答える
0

いくつかの拡張メソッド(ここでの例)を使用する場合は、コードを単純化できるはずです。

AccessModifierType modifier = Model.CurrentContext.CurrentAccessModifierType;
if (modifier.Has(AccessModifierType.Public) && 
    modifier.Has(AccessModifierType.Static) &&
    modifier.Has(AccessModifierType.Privileged) && 
    modifier.Has(AccessModifierType.Private))
{
}
于 2012-05-01T08:42:28.390 に答える