ここではC#の列挙型を学びましょう。簡単に言うと、すでに学んだ定数の強化版です。
ここではC#の定数を学びましょう。 定数 (constants) 定数とは名前の通りで固定された値です。つまりは変数のように値を変更することができません。また、仮に定数を変更しようと試みるとビルドエラーになるので、変更するという行為自体が禁止されます。 これのメリットは、コーディングのミス等で本来変えてはいけない数値を触る危険性を回避できます。また、定数は変数のように名前を与えることができるので、0や1など意味不明な数値を減らすことができます。 定数を定義する方法...
列挙型 (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配下なら大丈夫くらいの認識でいいです。
ここではC#のアクセス修飾子について学びます。これもクラスの延長線の話になります。最低でもクラスと継承の知識が必要なので、忘れてしまった人は以下で復習しましょう。 アクセス修飾子(Access Modifiers) アクセス修飾子とは、クラス、メソッド、プロパティ、フィールド等へのアクセス範囲を制限するために使います。 既に解説したprivateとpublicを含めると、全部で5種類(public, protected, internal, private, f...
ここではC#の名前空間について学びます。 名前空間 (namespace) 名前空間とは、複数のクラス等を1つの領域にまとめる機能です。この仕組みを使うことで、ある程度の機能を1つのスコープにまとめることができます。 名前空間を定義する方法 まとめたい領域をnamespaceと{}で囲みます。実は最初から何度も登場してますが、改めて確認しましょう。 では、以下が構文とサンプルコードです。 // 名前空間のOSを定義 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#に関する学習コンテンツ
この記事は参考になりましたか?
コメント