列挙型(enumeration)を理解しよう!

[C#] 列挙型(enumeration)を理解しよう!

※ 当サイトは広告を含みます。

ここではC#の列挙型を学びましょう。簡単に言うと、すでに学んだ定数の強化版です。

列挙型 (enumeration)

列挙型とは、定数を連番として扱い型の概念を追加できる機能です。
この型の概念を追加できるのが定数との大きな違いです。

では、構文とサンプルコードを確認してみましょう。

列挙型

namespace Sample
{
  // Enum型でSeason型を定義する
  enum Season
  {
    Spring, // Season型の列挙値
    Summer, //   〃
    Autumn, //   〃
    Winter, //   〃
  }

  internal class Program
  {
    static void Main(string[] args)
    {
      Season season = Season.Spring; // Season型を利用する

      Console.WriteLine(season);      // 列挙値を表示
      Console.WriteLine((int)season); // 定数値を表示
    }
  }
}

まず、今までのサンプルコードとは記述場所が異なりますよね。
Enum型と言いますが、これを定義できるのはnamespace配下class配下のみです。

このことを詳しく説明するにはアクセス修飾子の概念を知ってる必要があります。
今回はそこまで話さないので、今はnamespace配下なら大丈夫くらいの認識でいいです。

では、改めてサンプルコードの重要なポイントを確認しましょう。


enum Season
{
  Spring,
  Summer,
  Autumn,
  Winter,
}

このようにEnum型は自分で新しい型を定義できます。
今回はSeason型として4つの定数(Spring, Summer, Autumn, Winter)を定義しました。

これの凄いところは、Season型は定義した4つの値しか取れないことです。
他の値を代入できないということは、それだけバグの可能性が減るということ。
また、普通に定数を作ってint型で扱うよりも分かりやすく、コードの可読性が上がります。

列挙値の定数値

列挙型は定数と言いましたよね。つまり定義した列挙値には値が割り振られます。
この時の割り振りはルールが決まっていて、0, 1, 2. . .とint型の連番が指定されます。

先程の例だと一部が省略されていて、仮に省略せずに記述するとこうなります。


enum Season : int
{
  Spring = 0,
  Summer = 1,
  Autumn = 2,
  Winter = 3,
}

このように型の指定と列挙値の指定が可能です。
また、型指定できる型は整数型(byte, sbyte, short, ushort, int, uint, long, ulong)のみです。

加えて列挙値ですが、これは開始番号のみを指定したり途中から指定することもできます。
具体例になるサンプルコードを用意したので見てみましょう。


namespace Sample
{
  enum Season
  {
    Spring = 100,
    Summer,
    Autumn,
    Winter = 200,
  }

  internal class Program
  {
    static void Main(string[] args)
    {
      Console.WriteLine((int)Season.Spring);
      Console.WriteLine((int)Season.Summer);
      Console.WriteLine((int)Season.Autumn);
      Console.WriteLine((int)Season.Winter);
    }
  }
}
りさ
りさ

逆に分かりづらくなってませんか?

管理人
管理人

いい疑問だね。その通りで中途半端な割り振りはバグの元だよ。
少なくとも意図的に全ての列挙値に値を割り振るか、一切割り振らないかの2択がオススメだよ。

列挙値を数値として扱う

列挙型は何れかの整数型を元に作成されてます。故にint型(変えてる場合は変更した型)にキャストしてもOKと、C#の言語レベルで決まってます。
サンプルコードでも利用してますが、以下のような記述で問題が起きることはありません。


Console.WriteLine((int)Season.Spring);

ただし、その逆は注意してください。以下のような記述をしてもビルドエラーにはなりません。


Season season = (Season)10;
りさ
りさ

これどうなるんですか?

管理人
管理人

普通に10って値が設定される。後、表示すると列挙値じゃなくて定数値が表示されるよ。
サンプルコードを用意したから動作確認したい人は試してみてね。


namespace Sample
{
  enum Season
  {
    Spring,
    Summer,
    Autumn,
    Winter,
  }

  internal class Program
  {
    static void Main(string[] args)
    {
      Season season = (Season)10; // 存在しない列挙値を代入する

      Console.WriteLine(season);
    }
  }
}

あとがき

数値型の定数だけで済まさずに独自Enum型を作成するとコードの可読性は格段に上昇しますよ。

◆ C#に関する学習コンテンツ

この記事は参考になりましたか?

関連記事

コメント

この記事へのコメントはありません。