基礎から学ぶC#入門 90日コース | アプリを作りながら学ぶ - Day 73:Create

Web APP 90日で身につけるC#
スポンサーリンク
スポンサーリンク

Day 73 のゴールと全体像

Day 73 では、タスク管理アプリの最初の機能、 「タスクを追加する(Create)」機能を形にしていきます。

昨日までに設計した TaskItem のクラスを土台にして、

  • コンソールから入力を受け取って
  • 必要な値を整えて
  • タスクとして生成し
  • 一覧に追加する

という一連の流れを、ステップバイステップで組み立てていきます。

「タスクが1件、ちゃんと追加されて一覧に並ぶ」 この瞬間は、アプリが一気に“生き物”っぽく感じられるところです。

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; // 次に割り当てるID

    // タスク追加
    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;
    }

    // IDで検索
    public TaskItem FindById(int id)
    {
        return _tasks.FirstOrDefault(t => t.Id == id);
    }
}
C#

今日は、この Add メソッドを中心に、 コンソールからの入力とつないでいきます。

入力の流れを考える

タスク追加に必要な情報

タスクを追加するときに、ユーザーから入力してもらいたい項目は次のとおりです。

  • タスク名(Title)
  • 詳細(Description)
  • 優先度(Priority)
  • 期限(DueDate)

IdCreatedAtIsCompleted は、 アプリ側で自動的に決めてしまうので、 ユーザーに入力してもらう必要はありません。

コンソールでの対話イメージ

こんな感じの対話をイメージしてみてください。

タスク名を入力してください: レポート作成
詳細(メモ)を入力してください: 明日までに提出するレポート
優先度を入力してください (1: 高, 2: 中, 3: 低): 1
期限を入力してください (yyyy-MM-dd、未入力なら期限なし): 2026-09-10
タスクを追加しました。ID: 1

この流れを、そのままコードに落とし込んでいきます。

入力を受け取るヘルパーメソッドを作る

タスク名の入力(必須)

タイトルは必須項目なので、 空文字が入らないように、ループでチェックします。

string ReadTitle()
{
    while (true)
    {
        Console.Write("タスク名を入力してください: ");
        string title = Console.ReadLine();

        // 空白だけの入力を防ぐ
        if (!string.IsNullOrWhiteSpace(title))
        {
            return title;
        }

        Console.WriteLine("タスク名は必須です。空では登録できません。");
    }
}
C#

詳細の入力(任意)

詳細は、空でも構わないのでシンプルに読み取ります。

string ReadDescription()
{
    Console.Write("詳細(メモ)を入力してください(空でも構いません): ");
    string description = Console.ReadLine();
    return description ?? string.Empty; // null の可能性をつぶしておく
}
C#

優先度の入力(1/2/3 のみ許可)

優先度は、決められた値だけを受け付けるようにします。

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 のいずれかで入力してください。");
    }
}
C#

ここでは int.TryParse を使って、 数値に変換できない入力をやさしく弾いています。

期限の入力(任意 + 日付形式チェック)

期限は、

  • 空なら「期限なし」
  • 入力があれば日付として解釈

というルールにします。

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 のように入力してください。");
    }
}
C#

このように、 入力のルールをヘルパーメソッドに閉じ込めておくと、 メインの処理がすっきりしていきます。

タスク追加機能を組み立てる

TaskRepository と入力ヘルパーをつなぐ

ここまでの部品を使って、 「タスク追加機能」をひとつのメソッドとしてまとめます。

// タスク一覧を管理するリポジトリ
TaskRepository repository = new TaskRepository();

void CreateTask()
{
    Console.WriteLine("=== タスク追加 ===");

    // 1. タスク名を入力
    string title = ReadTitle();

    // 2. 詳細を入力
    string description = ReadDescription();

    // 3. 優先度を入力
    int priority = ReadPriority();

    // 4. 期限を入力
    DateTime? dueDate = ReadDueDate();

    // 5. リポジトリに追加
    TaskItem task = repository.Add(title, description, priority, dueDate);

    // 6. 結果を表示
    Console.WriteLine($"タスクを追加しました。ID: {task.Id}");
}
C#

この CreateTask メソッドは、

  • コンソールとの対話
  • 入力値のチェック
  • TaskRepository への追加

をひとつの流れとしてまとめたものです。

メニューから呼び出す

コンソールアプリのメニューに、 「タスク追加」を組み込んでみます。

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();
    }
}
C#

これで、

  • メニューから「1」を選ぶとタスク追加画面へ
  • 入力が終わると「タスクを追加しました。ID: X」と表示される

という、Create 機能の基本形が完成します。

一覧表示で「追加されたこと」を確認する

シンプルな一覧表示

タスクがちゃんと追加されているかどうかを確認するために、 簡単な一覧表示機能も用意しておきましょう。

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} {status} 優先度: {priorityText} 期限: {dueText} タイトル: {t.Title}");
    }
}
C#

Day 73 の時点では、 「追加したタスクが一覧にちゃんと出てくる」 この確認ができれば十分です。

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} {status} 優先度: {priorityText} 期限: {dueText} タイトル: {t.Title}");
        }
    }
}
C#

Day 73 のまとめ

Day 73 では、

  • タスク追加に必要な項目を整理し
  • コンソールからの入力をヘルパーメソッドで丁寧に受け取り
  • TaskRepository の Add メソッドとつないで
  • 「タスクを追加しました。ID: X」と表示されるところまで 一連の Create 機能を形にしました。

タスク管理アプリの世界に、 最初の1件のタスクが生まれる瞬間―― それは、コードがただの文字列から、 少しだけ“道具”に変わる瞬間でもあります。

次の Day では、この Create 機能を土台にして、 一覧表示や検索、編集など、 タスクたちともっと深く付き合っていく機能を育てていきます。 今日の Create が、そのすべての出発点になってくれます。

タイトルとURLをコピーしました