基礎から学ぶC#入門 90日コース | 実践的なC#プログラミング - Day 55:JSON

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

Day 55 のゴールと全体像

Day 55 では、現代のプログラミングでは欠かせない存在になっている JSON をテーマにします。 今日のキーワードは次の4つです。

  • JSON形式
  • シリアライズ
  • デシリアライズ
  • C# オブジェクト → JSON → ファイル

昨日までの CSV に続いて、 「データをファイルに保存する」という流れを、 より“今っぽい”形で体験していくイメージですね。

Web API、設定ファイル、ログ、外部サービスとの連携など、 JSON は本当にあちこちで使われています。 ここでしっかりイメージをつかんでおくと、 この先の世界がぐっと広く、そして楽しく見えてきます。

JSON形式とは何か

「人間にも機械にも読みやすいデータの形」

JSON は JavaScript Object Notation の略で、 「JavaScript のオブジェクト表記をベースにしたデータ形式」です。

とはいえ、C# でも Python でも、 ほとんどの言語が JSON を扱えるようになっているので、 今では「言語をまたいでデータをやり取りするための共通フォーマット」として定着しています。

基本的な形は次のようなものです。

{
  "Id": 1,
  "Name": "山田太郎",
  "Email": "yamada@example.com"
}
JSON

特徴をざっくり挙げると、

  • {} でオブジェクト(1つのまとまり)を表現する
  • "キー": 値 のペアをカンマで区切って並べる
  • 文字列は "ダブルクォート" で囲む
  • 数値や真偽値(true / false)もそのまま書ける
  • 配列は [] で表現する

たとえば、ユーザー一覧はこうなります。

[
  {
    "Id": 1,
    "Name": "山田太郎",
    "Email": "yamada@example.com"
  },
  {
    "Id": 2,
    "Name": "佐藤花子",
    "Email": "hanako@example.com"
  }
]
JSON

「オブジェクト」と「配列」を組み合わせて、 複雑なデータ構造もわかりやすく表現できるのが、JSON の魅力です。

シリアライズとデシリアライズの考え方

「オブジェクトを文字列にする」「文字列からオブジェクトに戻す」

JSON を扱うときに、よく出てくる言葉が シリアライズデシリアライズ です。 少しカタカナが強めですが、意味はシンプルです。

  • シリアライズ(Serialize)
    • C# のオブジェクトを、JSON などの「文字列形式」に変換すること
  • デシリアライズ(Deserialize)
    • JSON の文字列を、C# のオブジェクトに戻すこと

イメージとしては、

C# オブジェクト
↓(シリアライズ)
JSON 文字列
↓(ファイルに保存)
JSON ファイル
↓(読み込み)
JSON 文字列
↓(デシリアライズ)
C# オブジェクト

という流れになります。

この「行ったり来たり」ができるようになると、

  • 設定をファイルに保存しておく
  • Web API から受け取った JSON をオブジェクトに変換する
  • オブジェクトを JSON にして別のサービスに送る

といったことが、自然にできるようになっていきます。

System.Text.Json を使った基本的なシリアライズ

まずは 1 つのオブジェクトを JSON にしてみる

C# では、.NET 標準の System.Text.Json を使って、 JSON のシリアライズ/デシリアライズができます。

まずは、ユーザークラスを定義して、 それを JSON に変換してみましょう。

using System;
using System.Text.Json; // JSON を扱うための名前空間

class User
{
    public int Id { get; set; }      // プロパティは public で get/set を持つ必要があります
    public string Name { get; set; }
    public string Email { get; set; }
}

class JsonSerializeExample
{
    public static void Run()
    {
        var user = new User
        {
            Id = 1,
            Name = "山田太郎",
            Email = "yamada@example.com"
        };

        // オブジェクトを JSON 文字列に変換(シリアライズ)
        string json = JsonSerializer.Serialize(user);

        Console.WriteLine("シリアライズした JSON:");
        Console.WriteLine(json);
    }
}
C#

ここでのポイントは次のとおりです。

  • JsonSerializer.Serialize(obj) で、オブジェクトを JSON 文字列に変換できます。
  • プロパティは public で、get / set を持っている必要があります。
  • クラス名ではなく、プロパティ名が JSON のキーになります。

出力される JSON は、だいたい次のような形になります。

{"Id":1,"Name":"山田太郎","Email":"yamada@example.com"}
JSON

少しコンパクトですが、 ちゃんと JSON として成立している形です。

JSON をファイルに保存する

「オブジェクト → JSON → ファイル」の流れを作る

次は、シリアライズした JSON をファイルに書き込んでみます。 Day 53 のファイル操作と組み合わせるイメージですね。

using System;
using System.IO;
using System.Text.Json;

class JsonFileExample
{
    public static void Run()
    {
        string folder = "data";
        string filePath = Path.Combine(folder, "user.json");

        if (!Directory.Exists(folder))
        {
            Directory.CreateDirectory(folder);
        }

        var user = new User
        {
            Id = 1,
            Name = "山田太郎",
            Email = "yamada@example.com"
        };

        // オブジェクトを JSON 文字列に変換
        string json = JsonSerializer.Serialize(user);

        // JSON をファイルに書き込む
        File.WriteAllText(filePath, json);

        Console.WriteLine($"ユーザー情報を JSON ファイル '{filePath}' に保存しました。");
    }
}
C#

ここで意識しておきたいこと:

  • シリアライズで得た JSON 文字列は、普通のテキストとしてファイルに書き込めます。
  • CSV と違い、「オブジェクトの構造」がそのまま JSON に反映されるので、 クラスの設計とファイルの中身が対応しやすいです。

JSON からオブジェクトに戻す(デシリアライズ)

ファイルから読み込んで、User に復元する

次は、保存した user.json を読み込んで、 User オブジェクトに戻してみます。

using System;
using System.IO;
using System.Text.Json;

class JsonDeserializeExample
{
    public static void Run()
    {
        string folder = "data";
        string filePath = Path.Combine(folder, "user.json");

        if (!File.Exists(filePath))
        {
            Console.WriteLine($"JSON ファイル '{filePath}' が存在しません。先に保存処理を実行してください。");
            return;
        }

        // JSON ファイルの内容を読み込む
        string json = File.ReadAllText(filePath);

        // JSON 文字列を User オブジェクトに変換(デシリアライズ)
        User user = JsonSerializer.Deserialize<User>(json);

        Console.WriteLine("JSON から復元したユーザー情報:");
        Console.WriteLine($"Id   : {user.Id}");
        Console.WriteLine($"Name : {user.Name}");
        Console.WriteLine($"Email: {user.Email}");
    }
}
C#

ここでのポイントは次のとおりです。

  • JsonSerializer.Deserialize<T>(json) で、JSON 文字列を型 T のオブジェクトに変換できます。
  • JSON のキーと、クラスのプロパティ名が一致している必要があります。
  • 型引数 <User> を指定することで、「User 型として復元してほしい」という意図を伝えています。

この「シリアライズ → ファイル保存 → デシリアライズ」の往復が、 JSON を使ったデータ保存の基本パターンになります。

配列(リスト)を JSON にする

ユーザー一覧を JSON 配列として保存する

JSON の強みは、配列を自然に扱えることです。 List<User> を JSON にして、ファイルに保存してみましょう。

using System;
using System.IO;
using System.Text.Json;
using System.Collections.Generic;

class JsonListExample
{
    public static void Run()
    {
        string folder = "data";
        string filePath = Path.Combine(folder, "users.json");

        if (!Directory.Exists(folder))
        {
            Directory.CreateDirectory(folder);
        }

        var users = new List<User>
        {
            new User { Id = 1, Name = "山田太郎", Email = "yamada@example.com" },
            new User { Id = 2, Name = "佐藤花子", Email = "hanako@example.com" },
            new User { Id = 3, Name = "鈴木一郎", Email = "ichiro@example.com" }
        };

        // ユーザー一覧を JSON にシリアライズ
        string json = JsonSerializer.Serialize(users);

        File.WriteAllText(filePath, json);

        Console.WriteLine($"ユーザー一覧を JSON ファイル '{filePath}' に保存しました。");
    }
}
C#

保存される JSON は、だいたい次のような形になります。

[
  {"Id":1,"Name":"山田太郎","Email":"yamada@example.com"},
  {"Id":2,"Name":"佐藤花子","Email":"hanako@example.com"},
  {"Id":3,"Name":"鈴木一郎","Email":"ichiro@example.com"}
]
JSON

JSON 配列を List<User> に戻す

using System;
using System.IO;
using System.Text.Json;
using System.Collections.Generic;

class JsonListReadExample
{
    public static void Run()
    {
        string folder = "data";
        string filePath = Path.Combine(folder, "users.json");

        if (!File.Exists(filePath))
        {
            Console.WriteLine($"JSON ファイル '{filePath}' が存在しません。");
            return;
        }

        string json = File.ReadAllText(filePath);

        // JSON 配列を List<User> にデシリアライズ
        List<User> users = JsonSerializer.Deserialize<List<User>>(json);

        Console.WriteLine("JSON から復元したユーザー一覧:");

        foreach (var user in users)
        {
            Console.WriteLine($"Id: {user.Id}, Name: {user.Name}, Email: {user.Email}");
        }
    }
}
C#

ここでの大事なポイント:

  • 配列(リスト)も、単一オブジェクトと同じようにシリアライズ/デシリアライズできます。
  • 型引数を List<User> にすることで、「ユーザーのリストとして復元してほしい」という意図を伝えています。

JSON とファイル操作をまとめたミニテンプレート

設定ファイルっぽいものを作ってみる

最後に、Day 55 の内容をひとつにまとめたミニテンプレートとして、 「アプリ設定」を JSON ファイルに保存・読み込みする例を紹介します。

using System;
using System.IO;
using System.Text.Json;

class AppSettings
{
    public string AppName { get; set; }
    public string Language { get; set; }
    public int MaxItems { get; set; }
}

class JsonSettingsExample
{
    private const string Folder = "data";
    private static readonly string FilePath = Path.Combine(Folder, "settings.json");

    // 設定を保存する
    public static void SaveSettings(AppSettings settings)
    {
        if (!Directory.Exists(Folder))
        {
            Directory.CreateDirectory(Folder);
        }

        // JSON にシリアライズ
        string json = JsonSerializer.Serialize(settings, new JsonSerializerOptions
        {
            WriteIndented = true // 見やすいように整形して出力するオプション
        });

        File.WriteAllText(FilePath, json);

        Console.WriteLine($"設定を JSON ファイル '{FilePath}' に保存しました。");
    }

    // 設定を読み込む
    public static AppSettings LoadSettings()
    {
        if (!File.Exists(FilePath))
        {
            Console.WriteLine("設定ファイルが存在しないため、デフォルト設定を返します。");

            return new AppSettings
            {
                AppName = "MyApp",
                Language = "ja-JP",
                MaxItems = 10
            };
        }

        string json = File.ReadAllText(FilePath);

        AppSettings settings = JsonSerializer.Deserialize<AppSettings>(json);

        Console.WriteLine("設定ファイルから読み込んだ内容:");
        Console.WriteLine($"AppName : {settings.AppName}");
        Console.WriteLine($"Language: {settings.Language}");
        Console.WriteLine($"MaxItems: {settings.MaxItems}");

        return settings;
    }

    public static void Run()
    {
        // 1. 設定を作って保存
        var settings = new AppSettings
        {
            AppName = "SampleApp",
            Language = "ja-JP",
            MaxItems = 20
        };

        SaveSettings(settings);

        // 2. 設定を読み込んで表示
        var loaded = LoadSettings();

        Console.WriteLine("最終的に使用する設定:");
        Console.WriteLine($"AppName : {loaded.AppName}");
        Console.WriteLine($"Language: {loaded.Language}");
        Console.WriteLine($"MaxItems: {loaded.MaxItems}");
    }
}
C#

このコードを実行すると、

  1. 設定を JSON ファイルに保存し
  2. その設定を読み込んでコンソールに表示し
  3. ファイルがない場合はデフォルト設定を返す

という、実際のアプリでもよくある流れを体験できます。

Day 55 のまとめ

Day 55 では、

  • JSON が「人間にも機械にも読みやすい、オブジェクトと相性の良いデータ形式」であること
  • シリアライズ(オブジェクト → JSON)とデシリアライズ(JSON → オブジェクト)の考え方
  • System.Text.Json を使った基本的なシリアライズ/デシリアライズの方法
  • 単一オブジェクトだけでなく、List<T> のような配列も JSON で扱えること
  • 設定ファイルやデータ保存に JSON を使うミニテンプレート

を、具体的なコード例とともに学びました。

JSON を扱えるようになると、

  • Web API と連携する
  • 設定やデータを柔軟に保存する
  • 他の言語やサービスと自然につながる

といったことが、ぐっと現実味を帯びてきます。

ぜひ、

  • プロパティを増やしてみる
  • リストの中身を変えてみる
  • JSON ファイルをテキストエディタで開いて眺めてみる

といった小さな実験を重ねながら、 「C# オブジェクト ↔ JSON ↔ ファイル」の流れを、 自分の手で自然に組み立てられるようになっていっていただければうれしいです。

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