2017-12-13 31 views
6

私は驚いていましたが、C#ではコンストラクタで列挙型を作成できます。 は例えば、私は、列挙型を持っている:enumコンストラクタを防ぐ方法

public enum Color 
{ 
    White = 1, 
    Red = 2 
} 

それからそれは次のように作成することができます。

var color = new Color(); 

そして、値が実際に有効な列挙値ではありません0になります。

したがって、何らかの理由で列挙型コンストラクタを禁止できますか?これを避ける方法は他のアイデアですか?

ありがとうございました。

+3

'var color =(Color)125;'も完全に合法です。 enum変数を読み取っているときに値が有効かどうかを手動でチェックする必要があります。 – Haukinger

+1

https://msdn.microsoft.com/en-us/library/ms182149.aspxを参照してください。フラグ列挙型ですか? – PaulF

+0

有効かどうかにかかわらず、値タイプのデフォルトは0であり、変更できません。あなたは何のためにenumを使っていますか?たぶん、より多くの文脈があれば、代替案を提案することができます。 – Equalsk

答えて

9

そこで、我々は何とか列挙型のコンストラクタを禁止することができますか?

問題は、コンストラクタ自体に厳密に関連していない番号:(Color)0基になる型が値0を持つことができるので、あまりにも有効です。これを回避する方法を

他のアイデア?

いいえ、これは基本的にはより広範な問題です。これを防止できる唯一の方法は、入力値の有効性を確認することです。

あなたはいつもCode Analysisに応じ0列挙値を持つ必要があります。

+1

enumに割り当てるには '0'をキャストする必要はありません。 –

+0

@MatthewWatson合意しましたが、コードサンプルは理解しにくいでしょう。 –

1

いいえ一般的に回避する方法はありません。静的アナライザーに警告することはできますが、列挙型が単なる数値であるという根本的な問題は解決されません。そのため、値123を持つことができます。さらに一般的に値0を持ちます(たとえば、または割り当てない)。

より明確に問題を参照するには、このことを考慮してください。

var colors = new Color[100]; 

colors[0]は今何ですか?初期化されていない番号と同様に、ゼロです。したがって列挙型を使用すると、値に名前を付けることができます。ではなく、は、型の変数がこれらの名前付き値の1つを使用することを保証しません。

列挙型の名前の値を常に0にすることをお勧めします(通常、この場合は「None」、「Uninitialised」、「NotSet」などと呼ばれます)。一度それを持っていれば、初期化されていない値は意味をなさないでしょう。

1

public enum Colorは、実際には列挙型の完全な宣言の短縮形です(public enum Color : int)。

enum 常には基本的な基本型を持ち、技術的には単純にその型の変数です。デフォルトでは、この型は32ビット整数で、32ビット整数をそのような列挙型に割り当てることができます。

実際の列挙型の定義は、単にあなたが変更したりしても、完全にコードを変更する必要なく、根本的な値を無視することができ、プログラミングで簡単に使用するため、その型のメンバーを名前が付けられています。

内部では、他のInt32値と同様に、タイプColor(ひどい名前)の列挙型は単なるInt32値です。as Anders Forsgren pointed outは、配列やあらゆる種類のグローバル変数ではデフォルトで0になります。これは公式ガイドラインがあなたのenumに常に0の定義を入れることを推奨する理由でもあります。

関連する問題