web-dev-qa-db-ja.com

enumプロパティが設定されているかどうかを確認するにはどうすればよいですか? C#

次のような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の値は「設定されていません」になります。これを行うより良い方法があります。提案されたメソッドは、乱雑になる可能性があります。

22
user2341534

デフォルトの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!
39
Michael Teper

基になるプライベートフィールドを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)に設定できないようにします。 colornullの場合、ユーザーが設定したことがないという100%の確実性があります。

getによって返されるデフォルト値はcatchのみですが、プログラムに一致する場合は常に例外をスローできます。

また、setがフィールドを設定するように設定することにより、指定した値がデフォルト値と等しくない場合(ユースケースに応じて)をさらに一歩進めることができます。

public Color Color
{
    get { return _color ?? Color.Black; }
    set
    {
        if (value != Color)
        {
            _color = value;
        }
    }
}
5
Sellorio

あなたは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
    }
}
2
jstromwick

列挙型は 値の型 です。つまり、他の場所に格納されているオブジェクトへの参照ではないため、nullにすることはできません。これらは常にintのようなデフォルト値を持ち、作成時にデフォルトでゼロになります。私は2つのアプローチを提案します:

  1. たとえば、Noneと呼ばれる値がゼロに等しい別の列挙型エントリを追加します。このように、列挙値は作成時にデフォルトでNoneになります。次に、if(foo.ColorType != Color.None)を確認できます。

  2. Colorプロパティを次のようにnull可能にしてください:public Color? ColorType { get; set; }。これで、デフォルトはnullになり、値nullを割り当てることができます。 nullableタイプの詳細については、こちらをご覧ください MSDN-Nullable Types(C#)

1
Sina Iravanian

enumは値タイプであるため、nullにすることはできません。また、ストレージは通常整数です。タイプに未定義の値が必要な場合は、

public enum Color
{
    Undefined,
    Red,
    Green,
}
0
ZZZ

あなたが発見したように、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);
0
Dave K