2012-01-26 10 views
4

私がフラグと非フラグの両方でenumを必要としているとします。enumのフラグと非フラグのバリエーション

  • オプション1:

    enum Color { Red, Blue, Green } 
    
    [Flags] 
    enum Colors { 
        None = 0, 
        Red = 1, 
        Blue = 2, 
        Green = 4 
    } 
    
    // use cases 
    Color currentColor; 
    Colors supportedColors; 
    
  • オプション2:私はすべてを複製することができ、私はちょうどすべてのためのフラグのバリアントを使用することができます。

    Colors currentColor; // ugly, since neither "None" nor "Red | Blue" should be valid 
    

私にはありません次のいずれかのように:オプション1では、Color.RedColors.Redは完全に無関係です。拘束力のあるコード。さらに、私は2つの列挙を同期させておく必要があります。オプション2の欠点は明らかです。私が実際に気に入っているのは、次のようなものです

enum Colors = Flag set of Color; 

この要件を満たすには、もっと優雅な解決策がありますか?

+0

ユースケースを拡張できますか? 'supportedColors'と' currentColor'を比較する必要はありますか? – Oded

+0

@Oded:はい、 'bool currentColorIsSupported =(currentColor And supportedColor <> 0)'のようなことをすることができれば嬉しいです。 – Heinzi

答えて

5

私は単純に[Flags]バージョンをすべて使用し、いくつかの場所で単なる値であることを確認します。あなたでも[Flags]せずに次が有効であるため、いずれかの方法ことを行う必要

var flags = (Color)47; // why not 

ですから、Colorあなたがとにかくを期待していたものであることを確認する必要があります。 [Flags]は、シリアライズ/解析だけに役立ちます。

2

オプション2の唯一の欠点は、ビットが不足していることです。それがあなたの問題なら、フラグ列挙型はあなたにはまったく適していません。代わりに、サポートされている色を作成します。HashSet<Color>

1

色と色(オプション1)という2つの列挙型は絶対に作成しないでください。これはあなたのコードを非常に混乱させるでしょう。

私が何かが欠けていない限り、私はオプション2がとても醜いとは思わない。一般に、実行時に設定する前に、システムパラメータをデフォルト値 "None"に初期化することは妥当です。

2

最近同じ問題がありました。オプション2で簡単なチェックで解決:

bool IsColorValid(Color color) 
{ 
    return (color != 0 && (color & (color - 1)) == 0); 
}