R.Tanaka.Ichiro's Blog

主にC# な話題です

目次

Blog 利用状況

ニュース

列挙型を使う(その3)

列挙型を使う
http://blogs.wankuma.com/rti/archive/2007/03/12/66244.aspx

列挙型を使う(その2)
http://blogs.wankuma.com/rti/archive/2007/03/13/66420.aspx

の続きです。

例えば、列挙型をアクセス権限に使用したい場合を考えてみます。
列挙したい項目は、「なし・読込・追加・更新・削除」です。

C# では、次のように定義することは既に述べました。


enum 権限 { なし, 読込, 追加, 更新, 削除 }


しかし、読込と更新のように2つの権限を持つ人がいた場合はどうしましょうか?
「読込と更新」という項目を追加することもできますが、そうすると全ての組み合わせを記述しなければなりません。

そこで、まず各値を2の累乗で指定してみます。


enum 権限 {
  なし = 0,
  読込 = 1,
  追加 = 2,
  更新 = 4,
  削除 = 8
}


こうすることで「読込と更新」の値は、1 + 4 = 5 と表せることになります。
逆に 5 は、必ず 1 + 4 の組み合わせによるということになります。
従って、5 という値だけで、1(読込) と 4(更新) の権限を持つことを表すことができます。

これは、全ての権限の組み合わせに有効な方法です。
しかし、列挙型には 5 という値は定義されていません。
以下の C# のコードを使って実行してみます。


for (int i = 0; i < 16; ++i) {
    Console.WriteLine( "{0} : {1}", i, ((権限)i).ToString());
}


すると、予想通り以下のように出力ウィンドウに表示されます。


0:なし
1:読込
2:追加
3:3
4:更新
5:5
6:6
7:7
8:削除
9:9
10:10
11:11
12:12
13:13
14:14
15:15


では、どうすれば組み合わせた数値の結果によって、対応する権限を取得できるのでしょうか?

その答えが FlagsAttribute 属性です。
列挙型の定義の先頭に[FlagsAttribute]と記述するだけです。


[FlagsAttribute]
enum 権限 {
  なし = 0,
  読込 = 1,
  追加 = 2,
  更新 = 4,
  削除 = 8
}


試しに、先ほどのコードを再度実行してみると次のように表示される筈です。


0:なし
1:読込
2:追加
3:読込, 追加
4:更新
5:読込, 更新
6:追加, 更新
7:読込, 追加, 更新
8:削除
9:読込, 削除
10:追加, 削除
11:読込, 追加, 削除
12:更新, 削除
13:読込, 更新, 削除
14:追加, 更新, 削除
15:読込, 追加, 更新, 削除


そんな訳で、某有名人Jねっとさんからの「まだぁ」という一言によって

予定を変更

して FlagsAttribute ネタをお送りしました。

投稿日時 : 2007年3月14日 14:25

Feedback

# re: 列挙型を使う(その3) 2007/03/14 15:03 シャノン

[Flags]
enum 権限 {
  なし = 0,
  読込 = 1,
  追加 = 2,
  更新 = 4,
  削除 = 8
}

# re: 列挙型を使う(その3) 2007/03/14 15:17 囚人

0x00000000
0x00000001
0x00000002
0x00000004
0x00000008
0x00000010
0x00000011

というように書いていかないと、17 以上が書きにくいと思うのは私だけでしょうか。

# re: 列挙型を使う(その3) 2007/03/14 15:18 囚人

間違いました。こうです。

0x00000000
0x00000001
0x00000002
0x00000004
0x00000008
0x00000010
0x00000020
0x00000040

# re: 列挙型を使う(その3) 2007/03/14 15:51 中博俊

入力チェックをできなければenumを理解したとはいえないですよね。
ね。

# re: 列挙型を使う(その3) 2007/03/14 22:50 黒龍

次あたりはParseとToStringでごにょごにょかな??

# re: 列挙型を使う(その3) 2007/03/15 10:08 R・田中一郎

シャノン さん

>[Flags]

FlagsAttribute と Flags の違いについて調べてみたのですが、よくわかりませんでした。

---------------------------------------------
囚人 さん

>というように書いていかないと、17 以上が書きにくいと思うのは私だけでしょうか。

僕は、サンプルのコードのように、1,2,4,8... を使いますねぇ。
しかし、扱う値が大きくなる場合は、囚人さんの書き方の方がわかりやすそうです。

---------------------------------------------
中博俊 さん

>入力チェックをできなければenumを理解したとはいえないですよね。

よくわからなかったので検索してみました。
検索キーワード:「入力チェック enum」

・・・よくわかりませんでした orz

---------------------------------------------
黒龍 さん

>次あたりはParseとToStringでごにょごにょかな??

うーん、実は、まだ何も考えていません。

# re: 列挙型を使う(その3) 2007/03/15 12:10 刈歩 菜良

> FlagsAttribute と Flags の違いについて調べてみたのですが、よくわかりませんでした。

[]ないで使うのであれば、同じだよ。
属性に使うクラス名は慣例としてすべてにAttributeが付いていて、指定するときにはそのAttributeが省略できる。

しかし、これが初心者には結構罠で、Attributeを外した名前と同名の別物クラスがあったりするからMSDN引く時は要注意。

# 列挙型を使う(その4) 2007/03/15 13:48 R.Tanaka.Ichiro's Blog

列挙型を使う(その4)

# re: 列挙型を使う(その3) 2007/03/15 14:50 R・田中一郎

刈歩 菜良 さん

>属性に使うクラス名は慣例としてすべてにAttributeが付いていて、指定するときにはそのAttributeが省略できる。

知りませんでした。

>しかし、これが初心者には結構罠で、Attributeを外した名前と同名の別物クラスがあったり

それはややこしい話ですね。
属性に使うクラスの場合は、確実に xxxAttribute クラスとして考えれば良いということですね。

# re: 列挙型を使う(その3) 2007/03/15 15:02 刈歩 菜良

> 属性に使うクラスの場合は、確実に xxxAttribute クラスとして考えれば良いということですね。
たぶん...
でも、実装上の縛りはなかったと思うので、つけないクラスも作れたはず(全く未確認)。

とりあえず、Attributeがついてなくてもつけてみて検索すればよいと思います。

# re: 列挙型を使う(その3) 2007/03/16 10:22 R・田中一郎

>とりあえず、Attributeがついてなくてもつけてみて検索すればよいと思います。

了解です。ありがとうございました。

# 列挙型を使う(その5) 2007/03/16 11:33 R.Tanaka.Ichiro's Blog

列挙型を使う(その5)

# 列挙型を使う(その6) 2007/03/19 10:05 R.Tanaka.Ichiro's Blog

列挙型を使う(その6)

タイトル  
名前  
Url
コメント