次のようなenumプロパティを持つクラスがあります:
public class Foo
{
public Color ColorType {get;set;}
}
public enum Color
{
Red,
Green,
}
これで、このクラスは次のように初期化できます。
var foo = new Foo();
colorTypeプロパティが設定されていない場合。今、私はメソッドを作成して、その列挙型が設定されているかどうかに関係なくアクションを実行しようとしています。たとえば、メソッドがあります。
private void checkEnum(Foo foo)
{
if(foo.ColorType !=null)
{
//perform these actions
}else
{
//perform those actions
}
}
ただし、値がnullになることはないという警告が表示され、さらに調査したところ、デフォルトで最初の値が設定されない場合、最初の値が赤になり、列挙型に値を追加することを検討していました。 「設定されていない」とし、その値を最初の値にします。設定されていない場合、enumの値は「設定されていません」になります。これを行うより良い方法があります。提案されたメソッドは、乱雑になる可能性があります。
デフォルトのenum値またはnull可能なenumの2つの方法のいずれかを使用できます。
デフォルトの列挙値
列挙型は整数によってサポートされ、int
のデフォルトはゼロなので、列挙型は常にデフォルトでゼロに相当する値に初期化されます。列挙値を明示的に割り当てない限り、最初の値は常にゼロ、2番目は1、というようになります。
public enum Color
{
Undefined,
Red,
Green
}
// ...
Assert.IsTrue(Color.Undefined == 0); // success!
null可能列挙型
割り当てられていない列挙型を処理するもう1つの方法は、null許容フィールドを使用することです。
public class Foo
{
public Color? Color { get; set; }
}
// ...
var foo = new Foo();
Assert.IsNull(foo.Color); // success!
基になるプライベートフィールドをnullにできるようにすることはできますが、プロパティはnullにできません。
例えば。
class SomeClass
{
private Color? _color; // defaults to null
public Color Color
{
get { return _color ?? Color.Black; }
set { _color = value; }
}
public bool ColorChanged
{
get { return _color != null; }
}
}
color == null
まだ設定されていないことがわかります。また、ユーザーがnull
(または他の回答で指定されているようにundefined
)に設定できないようにします。 color
がnull
の場合、ユーザーが設定したことがないという100%の確実性があります。
get
によって返されるデフォルト値はcatchのみですが、プログラムに一致する場合は常に例外をスローできます。
また、set
がフィールドを設定するように設定することにより、指定した値がデフォルト値と等しくない場合(ユースケースに応じて)をさらに一歩進めることができます。
public Color Color
{
get { return _color ?? Color.Black; }
set
{
if (value != Color)
{
_color = value;
}
}
}
あなたは2つの本当の選択肢があります。 1つ目は、列挙型に未定義の値を追加することです。これは、プロパティが初期化される前のデフォルト値になります。
1)
public enum Color
{
Undefined,
Red,
Green,
}
あなたのチェックで:
private void checkEnum(Foo foo)
{
if(foo.ColorType == Color.Undefined)
{
//perform these actions
}else
{
//perform those actions
}
}
2)あるいは、未定義の値を追加せず、プロパティをNullable
にするだけです
public class Foo
{
public Color? ColorType {get;set;}
}
public enum Color
{
Red,
Green,
}
次のようにチェックを実行します。
private void checkEnum(Foo foo)
{
if(!foo.ColorType.HasValue)
{
//perform these actions
}else
{
//perform those actions
}
}
列挙型は 値の型 です。つまり、他の場所に格納されているオブジェクトへの参照ではないため、null
にすることはできません。これらは常にint
のようなデフォルト値を持ち、作成時にデフォルトでゼロになります。私は2つのアプローチを提案します:
たとえば、None
と呼ばれる値がゼロに等しい別の列挙型エントリを追加します。このように、列挙値は作成時にデフォルトでNone
になります。次に、if(foo.ColorType != Color.None)
を確認できます。
Color
プロパティを次のようにnull可能にしてください:public Color? ColorType { get; set; }
。これで、デフォルトはnull
になり、値null
を割り当てることができます。 nullable
タイプの詳細については、こちらをご覧ください MSDN-Nullable Types(C#) 。
enum
は値タイプであるため、nullにすることはできません。また、ストレージは通常整数です。タイプに未定義の値が必要な場合は、
public enum Color
{
Undefined,
Red,
Green,
}
あなたが発見したように、C#の列挙型は参照型ではなく値の型(基本的に整数です)なので、デフォルトではNULLではなく、列挙型の最小の整数値になります。 enumを処理するときに、この関係が最も有用な属性の1つであるため、この関係を見失わないでください。あなたが明示的に述べるか否かに関わらず、
public enum Color
{
Red,
Green
}
次と等しい:
public enum Color
{
Red = 0,
Green = 1
}
もちろん、各列挙型メンバーに任意の整数値を与えることができます。
これを行うより良い方法があるかどうかに関しては、実際にはすべて「これ」が何であるかに依存しますが、次の列挙型設定を単に使用するという提案には何の問題もありません。
public enum Color
{
None = 0,
Red,
Green
}
一般に、名前から選択できるようにする可能性のある明確に有限で離散的な可能な値のセットがある場合は、列挙型を使用します。たとえば、パラメーターとして4つの基本方向(北、東、南、西)のいずれかを使用するメソッドがあるとします。それぞれの方向に時計回りに番号を付けることにしました。北は0から始まります。
public enum Direction
{
North = 0,
East,
South,
West
}
これで、関数が整数パラメーターを取り、各数値が何を参照しているかを覚えていると信頼する代わりに、関数が列挙型メンバーをパラメーターとして取り、どの方向を処理しているかをすぐに知ることができます。例えば:
getNeighbor(1);
次のように読みやすくなります:
getNeighbor(Direction.East);