2011-08-18 15 views
3

列挙型のエントリのいくつかのプロパティを定数に格納する必要があります。たとえば、色が冷たいか暖かいかを示します。列挙型の値の生成定数

enum Colors 
{ 
    Yellow, // warm 
    Blue, // cold 
    Gray, // cold 
    Red, // warm 
    // etc. 
} 

私は、定数のビットマスクを生成するマクロを定義します。以下のような 何か:何のマクロが存在しないため

#define WARM 1 
#define COLD 0 

#define MAKECOLOR(index, type) ((index << 8) | type) 

enum Colors 
{ 
    Yellow = MAKECOLOR(0, WARM), 
    Blue = MAKECOLOR(1, COLD), 
    Gray = MAKECOLOR(2, COLD), 
    Red = MAKECOLOR(3, WARM), 
    // etc. 
} 

C#のではこれは不可能です。私はビットマスク表現を直接列挙型に書くのは避けたい。このように:

... 
    Gray = ((2 << 8) | 0), 
    ... 

どのようなアイデアですか?

P.S.
はい、私は構文的な砂糖フリークです。 :D

答えて

3

enum値で属性を使用する必要があります。この記事を読んで、それはかなり良いことだ:

http://www.codeproject.com/KB/cs/enumwithdescription.aspx

はそれが役に立てば幸い!

+0

良いアイデア。唯一の問題は、属性の評価がどれだけ速いかということです。 – armen

+0

この解決策では、リフレクションを使用するとパフォーマンスが低下します。各列挙型メンバのプロパティをspeedの値に含める場合は、別のWarm/Coldアレイを使用し、列挙型メンバの整数値をインデックスとして使用することもできます(たとえば、 'warmcold [(int)Colors.Gray]' – Virtlink

+1

まあ、彼らは反射を通してアクセスされるので、光の速度を期待しないでください。 –

2

私はが列挙型で直接ビット表現を書くことが多いん

enum Colors 
{ 
    Yellow = (0 << 8) | ColorTemp.Warm, 
    Blue = (1 << 8) | ColorTemp.Cold, 
    Gray = (2 << 8) | ColorTemp.Cold, 
    Red = (3 << 8) | ColorTemp.Warm, 
} 

enum ColorTemp 
{ 
    Cold = 0, 
    Warm = 1, 
} 

そして、このように、ファイルの一番下に簡単な拡張クラスを記述します。

public static class ColorsExtensions 
{ 
    public ColorTemp GetTemperature(this Colors color) 
    { 
     return (ColorTemp)(color & 0x01); 
    } 
} 
+0

これはプロパティを取得する方法です。代わりに、それを定義する方法が必要です。 – armen

+0

@armen:これは –

0

C#では、enumは、コンパイル時に定義された値がconstである必要があります。つまり、C#はC++よりもconstです。

C#では、constはコンパイル時の定数式を表すのに使用されます。それは、このC++コードに似ていると思います:

enum { 
    count = buffer.Length; 
} 

buffer.Lengthは、実行時に評価されているので、それは定数式ではない、ので、これはコンパイルエラーを生成します。

C#にはreadonlyキーワードがあります。これはC++のconstと少し似ています。 (しかし、それでもまだはるかに制限されており、C#ではconst-correctnessというものはありません)。

constは、読み込み専用の値ではなく、コンパイル時の定数を表すためのものです。

C#で読み込み専用ではなく非コンパイル時定数のローカル変数を指定することはできません。いくつかのローカル変数は、foreachループ内の反復変数とusingステートメントの最初の部分で宣言された変数など、本質的に読み取り専用です。ただし、独自の読み取り専用変数を作成することはできません。

メソッド内でconstを使用すると、その識別子のすべての使用がコンパイル時の定数値で置き換えられます。

したがって、コンパイル時にenumの値を定義する必要があります。実行時に評価することはできません。それらはルールです。

+0

まあ、 '(3 << 8)| Warm'のような式はコンパイル時に評価されますが、'(3 << 8)| Warm '静的関数呼び出しは、強力な最適化の問題です。 – Vlad

+0

@Vlad:C#で静的関数呼び出しを試みましたが、コンパイラは定数でなければならないと不満を募らせました。 'enum'のコンパイル時に評価されるため、動作します。 –

+0

これは基本的に、言語のオプティマイザが恥ずかしがり屋であり、コンパイル時に完全な強さを評価することを望みません。結局のところ、考えられる式はコンパイル時定数です。 – Vlad