Day 47 のゴールと全体像
Day 47 のテーマは enum(列挙型)と状態管理です。
キーワードはこの2つです。
- 列挙型
- 状態管理
ここまで、クラス・継承・インターフェース・依存関係と、 「オブジェクトの設計」を中心に見てきましたが、 Day 47 では、
「オブジェクトの“状態”を、わかりやすく・安全に表現する」
ための道具として、enum をじっくり扱っていきます。
列挙型(enum)とは何か
「限られた選択肢を名前で表すための型」
enum(列挙型)は、
「この値は、決められた候補のどれかである」
ということを、 名前付きの定数の集合として表現するための仕組みです。
たとえば、
- 会員ランク:
Bronze,Silver,Gold - 注文ステータス:
Pending,Processing,Completed,Cancelled - アプリの状態:
Idle,Running,Paused,Stopped
など、 「限られた選択肢の中からひとつを選ぶ」場面で活躍します。
まずはシンプルな enum を定義してみる
会員ランクを表す MembershipRank
// 会員ランクを表す列挙型
enum MembershipRank
{
Bronze, // ブロンズ会員
Silver, // シルバー会員
Gold // ゴールド会員
}
C#ここでのポイントは、
enumキーワードで列挙型を宣言する- 中に「取りうる値」を列挙して書く
- 各値は、実際には整数(0, 1, 2, …)として扱われますが、 コード上は「名前」で扱える
というところです。
enum を使って状態を持つクラスを作る
会員クラス Member にランクを持たせる
using System;
// 会員クラス
class Member
{
public string Name { get; set; }
// 会員ランクを enum で管理する
public MembershipRank Rank { get; set; }
public Member(string name, MembershipRank rank)
{
Name = name;
Rank = rank;
}
// 会員情報を表示するメソッド
public void ShowInfo()
{
Console.WriteLine($"名前: {Name}");
Console.WriteLine($"ランク: {Rank}");
}
}
C#使う側はこうなります。
class Program
{
static void Main(string[] args)
{
// ゴールド会員を作成
Member m1 = new Member("山田", MembershipRank.Gold);
// シルバー会員を作成
Member m2 = new Member("佐藤", MembershipRank.Silver);
m1.ShowInfo();
Console.WriteLine();
m2.ShowInfo();
Console.ReadLine();
}
}
C#ここで注目してほしいのは、
- ランクを
stringではなくMembershipRankという 専用の型で表現していること MembershipRank.Goldのように、 「名前付きの定数」として扱えること
です。
重要ポイント:
- enum を使うと、「この値はこの候補のどれかである」ということを 型レベルで表現できるようになります。
enum を使うメリット
1. 間違った値を入れにくくなる
もしランクを string で管理していたら、
Rank = "Goold"; // スペルミス…
Rank = "VIP"; // 想定外の値…
C#のようなミスが、コンパイル時には検出されません。
一方、MembershipRank を使っていれば、
Rank = MembershipRank.Gold; // OK
Rank = MembershipRank.Silver; // OK
Rank = (MembershipRank)100; // こういう変なことは普通は書かない
C#というふうに、 「定義されていない値」をうっかり入れる可能性がぐっと減ります。
2. コードの意味が読みやすくなる
Rank = MembershipRank.Gold; と書いてあると、
- 「これは会員ランクであり、その値はゴールドである」
ということが一目で分かります。
Rank = 2; と書いてあるより、 ずっと読みやすいですよね。
3. 状態管理の分岐がわかりやすくなる
switch 文などで状態ごとの処理を分けるときも、 enum はとても役立ちます。
void ShowBenefit(MembershipRank rank)
{
switch (rank)
{
case MembershipRank.Bronze:
Console.WriteLine("ブロンズ会員特典:ポイント1倍");
break;
case MembershipRank.Silver:
Console.WriteLine("シルバー会員特典:ポイント1.5倍");
break;
case MembershipRank.Gold:
Console.WriteLine("ゴールド会員特典:ポイント2倍+特別クーポン");
break;
}
}
C#このように、 「状態ごとの処理」を書くときに、 enum はコードの意味をとてもクリアにしてくれます。
状態管理に enum を使う実践例
注文ステータスを表す OrderStatus
アプリケーションでは、「状態」を扱う場面がたくさんあります。 その代表例が「注文ステータス」です。
// 注文ステータスを表す列挙型
enum OrderStatus
{
Pending, // 受付待ち
Processing, // 処理中
Completed, // 完了
Cancelled // キャンセル
}
C#注文クラス Order
using System;
class Order
{
public int Id { get; set; }
public string CustomerName { get; set; }
// 注文の状態を enum で管理する
public OrderStatus Status { get; private set; }
public Order(int id, string customerName)
{
Id = id;
CustomerName = customerName;
Status = OrderStatus.Pending; // 初期状態は Pending
}
// 状態を「処理中」にする
public void StartProcessing()
{
if (Status != OrderStatus.Pending)
{
Console.WriteLine("この注文は、すでに処理中または完了・キャンセルされています。");
return;
}
Status = OrderStatus.Processing;
Console.WriteLine($"注文 {Id} を処理中に変更しました。");
}
// 状態を「完了」にする
public void Complete()
{
if (Status != OrderStatus.Processing)
{
Console.WriteLine("処理中の注文のみ完了にできます。");
return;
}
Status = OrderStatus.Completed;
Console.WriteLine($"注文 {Id} を完了に変更しました。");
}
// 状態を「キャンセル」にする
public void Cancel()
{
if (Status == OrderStatus.Completed)
{
Console.WriteLine("完了した注文はキャンセルできません。");
return;
}
Status = OrderStatus.Cancelled;
Console.WriteLine($"注文 {Id} をキャンセルに変更しました。");
}
// 注文情報を表示する
public void ShowInfo()
{
Console.WriteLine($"注文ID: {Id}");
Console.WriteLine($"顧客名: {CustomerName}");
Console.WriteLine($"状態: {Status}");
}
}
C#実際に状態を変えてみる
class Program
{
static void Main(string[] args)
{
Order order = new Order(1, "山田太郎");
order.ShowInfo();
Console.WriteLine();
order.StartProcessing();
order.ShowInfo();
Console.WriteLine();
order.Complete();
order.ShowInfo();
Console.WriteLine();
// 完了後にキャンセルしようとしてみる
order.Cancel();
order.ShowInfo();
Console.ReadLine();
}
}
C#ここでのポイントは、
OrderStatusという enum を使って、 注文の状態を「決められた候補のどれか」に限定していること- メソッド内で
Statusをチェックしながら、 「この状態のときだけ、次の状態に進める」というロジックを書いていること
重要ポイント:
- enum は「状態の種類」をはっきりさせることで、 状態遷移(状態の変化)のロジックを分かりやすくしてくれます。
enum と switch で状態ごとの処理を整理する
アプリの動作モードを表す AppMode
もうひとつ、アプリの「モード」を例にしてみます。
// アプリの動作モード
enum AppMode
{
Idle, // 待機中
Running, // 実行中
Paused, // 一時停止
Stopped // 停止
}
C#モードごとの処理を switch で分ける
using System;
class App
{
public AppMode Mode { get; private set; } = AppMode.Idle;
public void ChangeMode(AppMode newMode)
{
Mode = newMode;
Console.WriteLine($"モードを {Mode} に変更しました。");
}
public void Execute()
{
switch (Mode)
{
case AppMode.Idle:
Console.WriteLine("待機中です。何もしていません。");
break;
case AppMode.Running:
Console.WriteLine("アプリが動作中です。処理を実行しています。");
break;
case AppMode.Paused:
Console.WriteLine("一時停止中です。処理は止まっています。");
break;
case AppMode.Stopped:
Console.WriteLine("停止状態です。アプリは終了しています。");
break;
}
}
}
C#実行例
class Program
{
static void Main(string[] args)
{
App app = new App();
app.Execute();
Console.WriteLine();
app.ChangeMode(AppMode.Running);
app.Execute();
Console.WriteLine();
app.ChangeMode(AppMode.Paused);
app.Execute();
Console.WriteLine();
app.ChangeMode(AppMode.Stopped);
app.Execute();
Console.ReadLine();
}
}
C#このように、
- モードを
AppModeという enum で表現し switchで状態ごとのメッセージや処理を分ける
ことで、 「状態管理」がとても見通しのよいコードになります。
enum の基本テンプレート
最後に、 enum を使った状態管理の基本形をテンプレートとしてまとめます。
列挙型の定義
// 状態を表す列挙型
enum TaskStatus
{
NotStarted, // 未開始
InProgress, // 進行中
Done, // 完了
Failed // 失敗
}
C#状態を持つクラス
using System;
class Task
{
public string Name { get; set; }
public TaskStatus Status { get; private set; } = TaskStatus.NotStarted;
public Task(string name)
{
Name = name;
}
public void Start()
{
if (Status != TaskStatus.NotStarted)
{
Console.WriteLine("未開始のタスクのみ開始できます。");
return;
}
Status = TaskStatus.InProgress;
Console.WriteLine($"タスク「{Name}」を開始しました。");
}
public void Complete()
{
if (Status != TaskStatus.InProgress)
{
Console.WriteLine("進行中のタスクのみ完了できます。");
return;
}
Status = TaskStatus.Done;
Console.WriteLine($"タスク「{Name}」が完了しました。");
}
public void Fail()
{
if (Status == TaskStatus.Done)
{
Console.WriteLine("完了したタスクは失敗にできません。");
return;
}
Status = TaskStatus.Failed;
Console.WriteLine($"タスク「{Name}」が失敗しました。");
}
public void ShowStatus()
{
Console.WriteLine($"タスク名: {Name}, 状態: {Status}");
}
}
C#使う側
class Program
{
static void Main(string[] args)
{
Task task = new Task("レポート作成");
task.ShowStatus();
task.Start();
task.ShowStatus();
task.Complete();
task.ShowStatus();
Console.ReadLine();
}
}
C#このテンプレートをベースに、
- 自分のアプリの中で「状態」を持つもの(注文・タスク・画面・接続など)を探し
- その状態を enum で表現してみる
という練習をすると、 enum と状態管理の感覚がぐっと身近になります。
Day 47 のまとめ
Day 47 では、
- 列挙型(enum) → 「限られた選択肢」を名前付きの定数として表現する型
- 状態管理 → オブジェクトの状態を enum で表し、状態ごとの処理や遷移をわかりやすく書くこと
を、会員ランク・注文ステータス・アプリのモード・タスクの状態などの例を通して学びました。
enum は、
「この値は、この候補のどれかである」
ということを、 型としてはっきり宣言できる道具です。
それによって、
- 間違った値を入れにくくなる
- コードの意味が読みやすくなる
- 状態ごとの処理や遷移が整理しやすくなる
という、大きなメリットが生まれます。
ぜひ、
- 自分のコードの中で「状態」を扱っている場所を探してみる
- それを enum で表現し直してみる
switchやメソッドで状態ごとの処理を整理してみる
という小さな練習を通して、 enum を 「ただの便利機能」ではなく、 状態管理をきれいにするための頼れる相棒として、 少しずつ体に馴染ませていってください。
