8

各権限を個々の列または SQL サーバー テーブルに分割する代わりに、Flag属性をEnum使用してビット単位の操作で使用することを再考しています。私たちのアプリケーションは、リソース(読み取り、変更、更新)にアクセスするためのエンドポイント(残りのサービスからのものではない)を定義し、各ユーザーはたとえばアクセス許可を持つ資格があるBob has permissions to Read, Modify resource Xため、ボブが来てこのリソースにアクセスすると、ボブがアクセス許可 x を持っているかどうかを確認します。これをどこに適用するかは明らかです ここに私の疑問があります

  • ボブがフラグ付きの列挙型を使用してリソースに対する読み取り、書き込み、削除のアクセス許可を持っているとしますPermission.Read | Permission.Write | Permission.Delete。ビットごとの AND の最終結果は整数または別の Enum ですか?

  • この権限をデータベース テーブルに保存するには、列をinteger?にする必要があります。

  • 質問 1 への回答が「Bit wise と操作の整数値を表す列挙型Enumの別のプロパティを定義する必要がありますか?」Permissions

disclaimer:例で言及されているボブは、サイトのスタック オーバーフロー ネットワーク内のユーザーや個人を表すものではありません。ただの別キャラです

4

2 に答える 2

10

質問に順番に答えるには:

  • [Flags]に属性を設定しenum、正しい演算子 (&および|ビット単位の操作の場合)を使用すると仮定すると、それは本質的に両方です。結果を整数にキャストすると、ビット単位の値と関連する値が得られます。あなたの例では7。を使用する.ToString()と、値に 3 つの値がすべて含まれていることを示す文字列が返されます。どこかにメソッドがあると思いますが、HasFlags()私が見たほとんどのコードは、比較のために試行済みの真のビット単位のコードを使用しています。

    var x = Permissions.Read | Permissions.Write;
    if ((x & Permissions.Read) == Permissions.Read) { print "Success!"; }
    

    技術的な観点からは、C# のタイプ セーフは物事を正常に保つのに役立ち、同じ型の2 つの s を|ing またはing した結果は同じ型の別のものになりますが、すべての s は単純な整数であり、ほとんどの場合そのように扱うことができます。への/からの明示的なキャストが必要です。&enumenumenumint

  • はい、一体型である必要があります。列挙型のデフォルトの型は だとInt32思いますが、データベースとコードを正確に一致させたい場合は明示的に設定できます。

  • 上記のすべてを考えると、一般的に使用されるアクセス許可のセット (たとえばReadWrite. 特に、None特に値をキャストする場合は、Microsoft によってすべての列挙型に対して要素が推奨されます。これにより、新たに初期化された変数のフォールバックと有効な値、および の正常な値が可能になりますdefault(Permissions)。次のように、他の値に基づいて列挙型に値を設定できます。

    [Flags]
    enum Permissions {
      None =    0,
      Read =    0x001,
      Write =   0x010,
      Execute = 0x100,
      ReadWrite = Read | Write,
      // [snip]
    }
    
于 2012-04-23T04:58:56.570 に答える
5
  1. [Flags] でマークされた列挙型の値のビットごとの OR/AND は、同じ列挙型の値です。
  2. 整数は、列挙値をデータベースに格納するのに適切なフィールドです。
  3. いいえ、追加の列挙値を追加する必要はありませんが、利便性のためにそうすることができます。

通常、そのような列挙型はFlagsAttributeで定義します。

[Flags] enum My {
  None = 0, Read =1, Write =2, Delete = 4
};

このように定義すると、異なる値を | で組み合わせることができます。(または) 操作:

My readAndWrite = My.Read | My.Write;

ビットごとの AND は、一意のフラグを表す列挙値に対して 0 を返しますが、他のビットをマスクするために一般的に使用されます。

bool doIHaveWrite = (readAndWrite & My.Write) == My.Write;

論理積 (&&) は列挙値には適用できないことに注意してください。

于 2012-04-23T04:57:21.230 に答える