Day 74 のゴールと全体像
Day 74 では、タスク管理アプリの「R」――Read(読み取り)機能をしっかり形にしていきます。 昨日までで「タスクを追加する(Create)」ところまではできましたので、 今日はそのタスクたちを 一覧として、わかりやすく表示する機能を作っていきます。
タスク管理アプリにとって、一覧画面はまさに「顔」です。 ここが見やすいかどうかで、アプリの印象がガラッと変わります。 ですので、単に「表示できればOK」ではなく、 読みやすさ・情報の整理・ちょっとした気遣いまで意識して設計していきます。
タスク一覧機能の役割を整理する
一覧機能は何をしてくれるのか
タスク一覧機能の役割は、ざっくり言うと次の3つです。
- 登録されているタスクをすべて取り出す
- 人間にとって読みやすい形に整形する
- 「何もないとき」はそれも分かりやすく伝える
プログラム的には「リストをループして表示するだけ」に見えますが、 実際には、
- 完了状態をどう表現するか
- 優先度をどう見せるか
- 期限がないタスクをどう扱うか
といった細かい設計が、使い心地に大きく影響してきます。
前提となる TaskItem と TaskRepository のおさらい
タスクの形:TaskItem
まずは、タスクのデータ構造をもう一度確認しておきます。
// タスクを表すクラス
class TaskItem
{
public int Id { get; set; } // 一意なID
public string Title { get; set; } // タスク名
public string Description { get; set; } // 詳細・メモ
public int Priority { get; set; } // 優先度(1: 高, 2: 中, 3: 低)
public DateTime? DueDate { get; set; } // 期限(任意)
public bool IsCompleted { get; set; } // 完了フラグ
public DateTime CreatedAt { get; set; } // 作成日時
}
C#タスク一覧を管理するクラス:TaskRepository
タスクを追加したり、一覧を取得したりする役割を持つクラスです。
using System;
using System.Collections.Generic;
using System.Linq;
// タスク一覧を管理するクラス
class TaskRepository
{
private readonly List<TaskItem> _tasks = new List<TaskItem>();
private int _nextId = 1;
// タスク追加
public TaskItem Add(string title, string description, int priority, DateTime? dueDate)
{
var task = new TaskItem
{
Id = _nextId++,
Title = title,
Description = description,
Priority = priority,
DueDate = dueDate,
IsCompleted = false,
CreatedAt = DateTime.Now
};
_tasks.Add(task);
return task;
}
// 全タスク取得
public IEnumerable<TaskItem> GetAll()
{
return _tasks;
}
}
C#Day 74 では、この GetAll() を使って一覧表示を作っていきます。
一覧表示の基本設計を考える
どんな情報を表示したいか
一覧画面に出したい情報を整理してみます。
- ID:編集や削除のときに指定するための識別子
- 完了状態:終わっているかどうかがひと目で分かるように
- 優先度:どれから手をつけるべきかの目安
- 期限:締め切りが近いものを意識するため
- タイトル:タスクの内容をざっくり把握するため
これらを、1行または数行で読みやすく表示するのが目標です。
空のときの振る舞い
タスクが1件も登録されていないときに、 何も表示されないと「壊れているのかな?」と不安になります。
ですので、
- タスクが0件なら「タスクが登録されていません。」と表示する
という振る舞いを、あらかじめ決めておきます。
タスク一覧表示の基本コード
シンプルな一覧表示メソッド
まずは、基本形となる一覧表示メソッドを書いてみます。
using System;
using System.Linq;
void ShowTasks()
{
Console.WriteLine("=== タスク一覧 ===");
// リポジトリから全タスクを取得
var tasks = repository.GetAll();
// タスクが1件もない場合
if (!tasks.Any())
{
Console.WriteLine("タスクが登録されていません。");
return;
}
// タスクがある場合、1件ずつ表示
foreach (var t in tasks)
{
// 完了状態を文字に変換
string status = t.IsCompleted ? "[完了]" : "[未完了]";
// 優先度を文字に変換
string priorityText = t.Priority switch
{
1 => "高",
2 => "中",
3 => "低",
_ => "不明"
};
// 期限を文字に変換(期限なしの場合の扱いも含める)
string dueText = t.DueDate.HasValue
? t.DueDate.Value.ToString("yyyy-MM-dd")
: "期限なし";
// 1行で表示する基本形
Console.WriteLine(
$"ID: {t.Id} {status} 優先度: {priorityText} 期限: {dueText} タイトル: {t.Title}"
);
}
}
C#重要ポイントの深掘り
tasks.Any()のチェックAny()は「1件でもあるか?」を調べるメソッドです。 これで「空かどうか」を簡潔に判定できます。- 完了状態の表現
IsCompletedはboolですが、そのままTrue/Falseと表示しても分かりづらいので、[完了] / [未完了]に変換して、人間にとって読みやすくしています。 - 優先度の表現 数値(1,2,3)を「高・中・低」に変換することで、 一覧を見たときに直感的に理解できるようになります。
- 期限の表現
DateTime?は「null を許す型」なので、HasValueで「期限があるかどうか」を判定し、 ない場合は「期限なし」と表示しています。
一覧表示を少し“見やすく”する工夫
カード風に表示してみる
1行に詰め込むのも悪くはないのですが、 タスクが増えてくると、少し読みづらく感じることもあります。
そこで、1件のタスクを「カード」のように複数行で表示してみます。
void ShowTasks()
{
Console.WriteLine("=== タスク一覧 ===");
var tasks = repository.GetAll();
if (!tasks.Any())
{
Console.WriteLine("タスクが登録されていません。");
return;
}
foreach (var t in tasks)
{
string status = t.IsCompleted ? "[完了]" : "[未完了]";
string priorityText = t.Priority switch
{
1 => "高",
2 => "中",
3 => "低",
_ => "不明"
};
string dueText = t.DueDate.HasValue
? t.DueDate.Value.ToString("yyyy-MM-dd")
: "期限なし";
Console.WriteLine($"ID: {t.Id}");
Console.WriteLine($" 状態 : {status}");
Console.WriteLine($" 優先度 : {priorityText}");
Console.WriteLine($" 期限 : {dueText}");
Console.WriteLine($" タイトル: {t.Title}");
Console.WriteLine(); // タスク同士の間に空行を入れて見やすくする
}
}
C#こうすると、
- 1件1件が「まとまり」として目に入る
- 状態・優先度・期限・タイトルが整理されて見える
というメリットがあります。
メニューから一覧機能を呼び出す
コンソールメニューとの連携
Day 73 で作ったメニューに、 「タスク一覧」を組み込んでいきます。
void Run()
{
while (true)
{
Console.WriteLine("=== タスク管理アプリ ===");
Console.WriteLine("1: タスク追加");
Console.WriteLine("2: タスク一覧");
Console.WriteLine("0: 終了");
Console.Write("選択してください: ");
string input = Console.ReadLine();
switch (input)
{
case "1":
CreateTask(); // Day 73 で作った追加機能
break;
case "2":
ShowTasks(); // 今日作った一覧機能
break;
case "0":
Console.WriteLine("終了します。");
return;
default:
Console.WriteLine("不正な入力です。");
break;
}
Console.WriteLine(); // 画面の区切り用に空行を入れる
}
}
C#これで、
- 「1」でタスク追加
- 「2」でタスク一覧
- 「0」で終了
という、基本的な C(Create)と R(Read) の流れが完成します。
Day 74 用ミニテンプレート(まとめて貼れるサンプル)
Day 73 のコードに、今日の一覧機能を組み込んだ形のサンプルです。
using System;
using System.Collections.Generic;
using System.Linq;
// タスクを表すクラス
class TaskItem
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public int Priority { get; set; }
public DateTime? DueDate { get; set; }
public bool IsCompleted { get; set; }
public DateTime CreatedAt { get; set; }
}
// タスク一覧を管理するクラス
class TaskRepository
{
private readonly List<TaskItem> _tasks = new List<TaskItem>();
private int _nextId = 1;
public TaskItem Add(string title, string description, int priority, DateTime? dueDate)
{
var task = new TaskItem
{
Id = _nextId++,
Title = title,
Description = description,
Priority = priority,
DueDate = dueDate,
IsCompleted = false,
CreatedAt = DateTime.Now
};
_tasks.Add(task);
return task;
}
public IEnumerable<TaskItem> GetAll()
{
return _tasks;
}
}
class Program
{
static TaskRepository repository = new TaskRepository();
static void Main()
{
Run();
}
static void Run()
{
while (true)
{
Console.WriteLine("=== タスク管理アプリ ===");
Console.WriteLine("1: タスク追加");
Console.WriteLine("2: タスク一覧");
Console.WriteLine("0: 終了");
Console.Write("選択してください: ");
string input = Console.ReadLine();
switch (input)
{
case "1":
CreateTask();
break;
case "2":
ShowTasks();
break;
case "0":
Console.WriteLine("終了します。");
return;
default:
Console.WriteLine("不正な入力です。");
break;
}
Console.WriteLine();
}
}
static void CreateTask()
{
Console.WriteLine("=== タスク追加 ===");
string title = ReadTitle();
string description = ReadDescription();
int priority = ReadPriority();
DateTime? dueDate = ReadDueDate();
TaskItem task = repository.Add(title, description, priority, dueDate);
Console.WriteLine($"タスクを追加しました。ID: {task.Id}");
}
static string ReadTitle()
{
while (true)
{
Console.Write("タスク名を入力してください: ");
string title = Console.ReadLine();
if (!string.IsNullOrWhiteSpace(title))
{
return title;
}
Console.WriteLine("タスク名は必須です。空では登録できません。");
}
}
static string ReadDescription()
{
Console.Write("詳細(メモ)を入力してください(空でも構いません): ");
string description = Console.ReadLine();
return description ?? string.Empty;
}
static int ReadPriority()
{
while (true)
{
Console.Write("優先度を入力してください (1: 高, 2: 中, 3: 低): ");
string text = Console.ReadLine();
if (int.TryParse(text, out int value))
{
if (value == 1 || value == 2 || value == 3)
{
return value;
}
}
Console.WriteLine("優先度は 1, 2, 3 のいずれかで入力してください。");
}
}
static DateTime? ReadDueDate()
{
while (true)
{
Console.Write("期限を入力してください (yyyy-MM-dd、未入力なら期限なし): ");
string text = Console.ReadLine();
if (string.IsNullOrWhiteSpace(text))
{
return null;
}
if (DateTime.TryParse(text, out DateTime date))
{
return date;
}
Console.WriteLine("日付の形式が正しくありません。例: 2026-09-10 のように入力してください。");
}
}
static void ShowTasks()
{
Console.WriteLine("=== タスク一覧 ===");
var tasks = repository.GetAll();
if (!tasks.Any())
{
Console.WriteLine("タスクが登録されていません。");
return;
}
foreach (var t in tasks)
{
string status = t.IsCompleted ? "[完了]" : "[未完了]";
string priorityText = t.Priority switch
{
1 => "高",
2 => "中",
3 => "低",
_ => "不明"
};
string dueText = t.DueDate.HasValue
? t.DueDate.Value.ToString("yyyy-MM-dd")
: "期限なし";
Console.WriteLine($"ID: {t.Id}");
Console.WriteLine($" 状態 : {status}");
Console.WriteLine($" 優先度 : {priorityText}");
Console.WriteLine($" 期限 : {dueText}");
Console.WriteLine($" タイトル: {t.Title}");
Console.WriteLine();
}
}
}
C#Day 74 のまとめ
Day 74 では、タスク管理アプリの Read(一覧表示)機能を丁寧に作り上げました。
- タスク一覧を取得する
GetAll()を使い - 空の場合のメッセージを用意し
- 完了状態・優先度・期限を、人間にとって読みやすい形に整形し
- カード風の表示で、タスク1件1件が見やすくなるように工夫しました。
これで、
「タスクを追加する」 → 「一覧で確認する」
という、アプリの基本的な流れが完成しました。
次のステップでは、 この一覧表示を土台にして、
- 特定のタスクを探す検索機能
- 編集や削除の対象を選ぶための表示
など、さらに一歩踏み込んだ「Read」の世界に進んでいきます。
タスクが増えていくほど、 一覧表示のありがたみがじわじわと効いてきますので、 今日作ったこの機能を、ぜひ自分の手で動かしてみて、 「見えるって、やっぱり気持ちいいな」と感じてもらえたらうれしいです。
