C#の列挙型のデフォルト値として「0」を使用する意味は何ですか?別の番号で始まる列挙を宣言すると、次のようになります。
enum Color
{
Blue = 1,
Green,
Red,
}
次に、var color = default(Color)
-は「0」を返します。代わりに最小値が表示されることを期待していました。列挙の各メンバーが特定の数値に対応し、「0」が有効な値でない場合、この動作は問題を引き起こす可能性があります。
すべての値の型 (enum を含む) のデフォルト値はビットごとの 0 です。その結果、明示的に定義されていなくても、0 は常に enum の可能な値であることを意味します。
仕様は次のとおりです。デフォルト値の表
編集:詳細については、列挙型のMSDNを確認してください-enum
enum は、他の値の型 (通常は不可能) から派生するという点で特別な型ですが、そのバッキング型の値の型として動作します。列挙型は、一部の整数値のみをバッキング タイプとして使用できます。
注: @archil が指摘しているように、enum 自体で列挙された定数のリストに関係なく、enum 値にはバッキング型の任意の値を含めることができます。「FlagsAttribute」でマークされた列挙型の場合、この動作は通常予想されますが、通常の列挙型の場合は直感的ではない場合があります。
.NET フレームワークのある側面が特定の方法で設計された理由については、推測することしかできません。最も簡単な説明として、MSDN ドキュメントから次のコメントを強調したいと思います。
列挙型は、基になる型が Char 以外の任意の整数型である名前付き定数のセットです。基になる型が明示的に宣言されていない場合は、Int32 が使用されます。
.NET 列挙は本質的に整数型の拡張であることに注意してください。整数型のデフォルト値は 0 であるため、列挙型がその動作を継承するのは合理的です (説明したケースでは多少不便ですが)。
enum が存在しない値を持つ可能性は常にあります。そのため、Enum.IsDefined メソッドが存在します。
列挙型 E のデフォルト値は、式 (E)0 によって生成される値です。
これまでに複数の回答で述べられているように、固定サイズのデータ構造の「デフォルト」値は 0 です。構造メモリのサイズはゼロに設定され、「デフォルト」と見なされます。列挙型に独自の「デフォルト」値を定義する場合は、複数のオプションがあります。最も簡単なのは、独自の関数を作成して「最小の有効な列挙型」を提供することです。
private E GetDefaultEnum<E>()
{
return (E)(Enum.GetValues(typeof(E)).Cast<E>().Min<E>());
}
使用法:
enum Color
{
Blue = 1,
Green,
Red,
}
Color defaultColor = GetDefaultEnum<Color>();
MessageBox.Show(defaultColor.ToString()); // "Blue"
「デフォルト」値を決定する方法を明らかに変更できますが、この方法がニーズに最も適しているようです。
なぜ 0 がデフォルトの列挙値なのですか? ランタイム実装の容易さ。任意の値型のデフォルトはビット単位の 0 であり、おそらく null 参照はビット単位の 0 で表されます。したがって、デフォルト値でオブジェクトを最初に構築するには、そのサイズを知るだけで済みます。ランタイムは、オブジェクトの構造について何も認識したり処理したりする必要はありません。同様に、定義済みの値型コンストラクターは、メモリ範囲をゼロで埋めることしかできません。
好むと好まざるとにかかわらず、その通りです。それに応じて必要なことは、列挙型を設計するときに、適切なデフォルトの名前が何であれ、それに値 0 を与えることです。適切なデフォルトがない場合、そのような列挙型をパラメーターとして受け入れるメソッドは、それが適切に設定されていることを確認する可能性があります。例えば
void ProcessColor(Color c) {
if (c == 0)
throw new ArgumentException("Color is not set", "c");
//...
}
ポイントは、おそらく正の整数の可能な値が少ないことです。
なぜあまり肯定的ではないのですか?
ビットシフト操作で enum を正しく扱えるようにするため。
私は当然、開発者が変更できるデフォルト値について話しています。
理由はわかりませんが...
C# enum に関するドキュメントは次のとおりです: http://msdn.microsoft.com/en-us/library/sbbt4032.aspx
次の例に示すように、列挙子は初期化子を使用して既定値をオーバーライドできます。
enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};
この列挙では、要素のシーケンスは 0 ではなく 1 から強制的に開始されます。ただし、値が 0 の定数を含めることをお勧めします。詳細については、列挙型 (C# プログラミング ガイド) を参照してください。
値 0 に対応するプレースホルダー列挙値を常に含めることをお勧めします。そうしないと、問題が発生する可能性があります。この列挙値にはUndefined
、またはそのような名前を付けることができDefault
ます。
あなたの質問へのコメントで述べたように、非常に正当な理由がない限り、列挙型に値を使用しないことをお勧めします。必要に応じて、列挙型の MSDN プログラミング ガイドに従ってください。
enum
ですint
(デフォルト)。列挙型は、ソース コードの人間が判読できる int ですが、プログラムがコンパイルされると、 はなくenum
、 のみint
です。int のデフォルト値は 0 です。
このコード:
public enum test { One, Two, Three }
var x = test.One;
var y = 0;
IL では次のようになります。
IL_0001: ldc.i4.0
IL_0002: stloc.0
IL_0003: ldc.i4.0
IL_0004: stloc.1
では、int
(あなたが尋ねるように) デフォルト値が 1 である場合とそうでない場合があるのはどうしてでしょうか?