6

この説明は、デフォルト値の名前についてです 。C#:列挙型のデフォルト値はNoneまたはUnknownのどちらにする必要がありますか?

しかし、最近私が話をした多くの人々は、デフォルトの列挙値が有害で不必要であり、悪い習慣につながる可能性があると考えていました。

例として、次のことを考慮してください。

enum eJobStates
{
    JOB_STATE_INITIALISING,
    JOB_STATE_PROCESSING,
    JOB_STATE_DONE
};

ジョブがJOB_STATE_UNKNOWNであるとは意味がありませんが、そのジョブの監視に使用される可能性のある任意の構造がそのような値を使用できることは想像できます。

列挙型を定義するときにデフォルト値を作成することに関するベストプラクティス/経験則はありますか?それらは可能な限り絶対に避けるべきですか?

4

1 に答える 1

2

無効なデフォルト値は、基本的にデザインのバリエーションです。オブジェクトは、作成時に無効です。それが合理的であるとき、あなたはそれを避けるべきです。決してそれを「絶対に」避けるべきではありません。

一部の問題では、バリアント状態で開始する必要があります。その場合、あなたその無効な値について精神的に推論しなければなりません。名前を付けないようにすると、コードの表現力が低下します。あなたと後でコードを維持しなければならない人との間のコミュニケーションの観点からそれについて考えてください。

風下でそれに対処するのは面倒です。あなたはバリアント状態で開始しますが、それが適切になるまでに、それがもはやバリアントではないことを望んでいます。私が好む戦略は、ユーザーがバリアントの状態を無視して、間違えたときにスローすることを許可することです。

namespace FooType {
  enum EnumValue {
    INVALID = 0
    ,valid
  };
}

struct Foo {
  Foo() : val(FooType::INVALID) {}
  FooType::EnumValue get() const {
    if (val == FooType::INVALID)
      throw std::logic_error("variant Foo state");
    return val;
  }
  FooType::EnumValue val;
};

これにより、ユーザーは、戦う価値のある差異について推論する必要がなくなります。

それを回避できない場合、私は通常、安全なインターフェイスと安全でないインターフェイスに劣化することを好みます。

struct Foo {
  Foo() : val(FooType::INVALID) {}
  bool get(FooType::EnumValue& val_) const {
    if (val == FooType::INVALID)
      return false;
    val_ = val;
    return true;
  }
  FooType::EnumValue get() const {
    FooType::EnumValue val_;
    if (!get(val_))
      throw std::logic_error("variant Foo state");
    return val_;
  }
  FooType::EnumValue get_or_default(FooType::EnumValue def) const {
    FooType::EnumValue val_;
    if (!get(val_))
      return def;
    return val_;
  }
  FooType::EnumValue val;
};

これらの種類のインターフェースは、null値が予想されるデータベースなどに適しています。

于 2012-12-19T17:11:14.523 に答える