注
このコンテンツは、 フレームワーク設計ガイドライン (再利用可能な .NET ライブラリの規則、イディオム、パターン、第 2 版) から、Pearson Education, Inc. のアクセス許可によって再印刷されます。 そのエディションは2008年に出版され、その後 、本は第3版で完全に改訂されています。 このページの情報の一部が古くなっている可能性があります。
列挙型は特殊な種類の値型です。 列挙型には、単純列挙型とフラグ列挙型の 2 種類があります。
単純な列挙型は、小さな閉じた選択肢のセットを表します。 単純な列挙型の一般的な例は、一連の色です。
フラグ列挙型は、列挙型の値に対するビットごとの操作をサポートするように設計されています。 フラグ列挙型の一般的な例は、オプションの一覧です。
✔️ 列挙型を使用して、値のセットを表すパラメーター、プロパティ、および戻り値を厳密に型指定します。
✔️ DO は、静的定数の代わりに列挙型を使用することをお好みです。
❌ オープン セット (オペレーティング システムのバージョン、フレンドの名前など) には列挙型を使用しないでください。
❌ 将来使用することを目的とした予約済み列挙型の値は指定しないでください。
後の段階で、既存の列挙型に値を追加するだけでいつでも実行できます。 列挙型への値の追加の詳細については、「列挙型への値の追加」を参照してください。 予約値は、実際の値のセットを汚染するだけで、ユーザー エラーにつながる傾向があります。
❌ 1 つの値のみを持つ列挙型をパブリックに公開することは避けてください。
C API の将来の拡張性を確保するための一般的な方法は、予約済みパラメーターをメソッドシグネチャに追加する方法です。 このような予約済みパラメーターは、単一の既定値を持つ列挙型として表すことができます。 これは、マネージド API では実行しないでください。 メソッドのオーバーロードにより、将来のリリースでパラメーターを追加できます。
❌ 列挙型に sentinel 値を含めないでください。
フレームワーク開発者には役立つことがありますが、Sentinel の値はフレームワークのユーザーにとっては混乱を招きます。 これらは、列挙型によって表されるセットの値の 1 つではなく、列挙型の状態を追跡するために使用されます。
✔️ 単純な列挙型に 0 の値を指定します。
値を "None" のような呼び出しを検討してください。このような値がこの特定の列挙型に適さない場合は、列挙型の最も一般的な既定値に基になる値 0 を割り当てる必要があります。
✔️ 次のいずれかが当てはまる場合を除き、列挙型の基になる型として Int32 (ほとんどのプログラミング言語では既定) を使用することを検討してください。
列挙型はフラグ列挙型であり、32 個を超えるフラグを持っているか、将来さらに多くを持つ予定です。
異なるサイズの列挙型を必要とするアンマネージ コードとの相互運用性を容易にするために、基になる型は Int32 とは異なる必要があります。
基になる型が小さいと、領域が大幅に節約されます。 列挙型が主に制御フローの引数として使用されると予想される場合、サイズはほとんど違いを生じさせます。 サイズの節約は、次の場合に大きくなる可能性があります。
列挙型は、非常に頻繁にインスタンス化される構造体またはクラスのフィールドとして使用されることが想定されています。
ユーザーは、列挙型インスタンスの大きな配列またはコレクションを作成することを想定しています。
列挙型の多数のインスタンスがシリアル化されることを想定しています。
メモリ内での使用では、マネージド オブジェクトは常に DWORD
アラインされているので、インスタンスの合計サイズは常に DWORD
に切り上げられますので、違いを生み出すために小さな列挙型をパックするために、インスタンス内の複数の列挙型またはその他の小さな構造体が効果的に必要であることに注意してください。
✔️ 複数形の名詞または名詞句を持つ DO 名フラグ列挙型と、単数形の名詞または名詞句を持つ単純な列挙型。
❌ System.Enumを直接拡張しないでください。
System.Enum は、ユーザー定義列挙型を作成するために CLR によって使用される特殊な型です。 ほとんどのプログラミング言語は、この機能にアクセスできるプログラミング要素を提供します。 たとえば、C# では、 enum
キーワードを使用して列挙型を定義します。
フラグ列挙型の設計
✔️ 列挙型にフラグを設定するには、 System.FlagsAttribute を適用します。 この属性は、単純な列挙型には適用しないでください。
✔️ フラグ列挙値に 2 の累乗を使用して、ビットごとの OR 演算を使用して自由に結合できるようにします。
✔️ 一般的に使用されるフラグの組み合わせに特別な列挙値を指定することを検討してください。
ビットごとの操作は高度な概念であり、単純なタスクには必要ありません。 ReadWrite は、このような特別な値の例です。
❌ 値の特定の組み合わせが無効な場合は、フラグ列挙型を作成しないでください。
❌ 次のガイドラインで規定されているように、値が "すべてのフラグがクリアされる" を表し、適切に名前が付けられている場合を除き、フラグ列挙値 0 を使用しないでください。
✔️ フラグ列挙型のゼロ値に None
名前を付けます。 フラグ列挙型の場合、値は常に "すべてのフラグがクリアされます" を意味する必要があります。
列挙型への値の追加
列挙型を既に出荷した後に値を追加する必要があることを発見するのは非常に一般的です。 新しく追加された値が既存の API から返されると、アプリケーションの互換性の問題が発生する可能性があります。これは、適切に記述されていないアプリケーションが新しい値を正しく処理しない可能性があるためです。
✔️ 互換性のリスクが小さいにもかかわらず、列挙型に値を追加することを検討してください。
列挙型への追加によって生じるアプリケーションの非互換性に関する実際のデータがある場合は、新しい値と古い値を返す新しい API を追加することを検討し、古い API を非推奨にして、古い値だけを返し続ける必要があります。 これにより、既存のアプリケーションに互換性が維持されます。
Portions © 2005, 2009 Microsoft Corporation. 無断転載を禁じます。
フレームワーク設計ガイドライン:再利用可能な .NET ライブラリの規則、イディオム、パターン、Krzysztof Cwalina および Brad Abrams による第 2 版は、2008 年 10 月 22 日に Microsoft Windows 開発シリーズの一部として Addison-Wesley Professional によって公開されました。