全てに中途半端なお豆

なんじゃこりゃ

System.Text.Jsonでjsonのデシリアライズに失敗してしまう

はじめに

こんばんは。まめプロと申します。よろしくお願いします。
この記事は備忘録と検証作業が酷すぎた反省の意味を込めて書きます。
何か間違っていることや、「この表現まずいよ」みたいなことがあれば指摘していただけると助かります。
かなりバカなミスなので、その所はご了承願います。

jsonをデシリアライズしたい人生だった

今作っているシューティングゲームで、敵の出現時間だったり出現方法をステージごとでうまく管理する方法が無いかを考えていて、「jsonで管理すればいいのでは」という発想に至り1、練習がてらにC#で事前に準備したjsonファイルをデシリアライズ2するサンプルコードを書いてみた。
次が実際に書いたサンプルコード&jsonファイルです。

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


namespace JsonTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            ReadJson("test.json", "utf-8");
        }
        static void ReadJson(string filePath, string encoding)
        {
            StreamReader streamReader = new StreamReader(filePath, Encoding.GetEncoding(encoding));
            string allLine = streamReader.ReadToEnd();
            streamReader.Close();
            Data data = JsonSerializer.Deserialize<Data>(allLine);
            Console.WriteLine(data.Id);
            Console.WriteLine(data.Name);
            Console.WriteLine(data.SpawnCount);
        }
    }
    class Data
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int SpawnCount { get; set; }
    }
}
{"id":11,"name":"NomalEnemy","spawncount":160}

実行結果

Hello World!
0

0

は?(は?)
なんで?(殺意)
0なんて数字、jsonで入れてないし、nameとして(出力の3行目には)「NomalEnemy」という単語が出てきてほしいのになんで?(殺意)
ちなみに期待していた出力結果は次の通り。

Hello World!
11
NomalEnemy
160

まじでなんで????

原因と解決策

というわけで、3時間ほど原因を調査したのですが、「調べてもよくわかりませんでした!来世に期待ですね!」でお馴染みの情報量0のまとめサイト状態になってしまった。
やけくそ気味で、jsonの変数名を次のように変更してみた。

{"Id":11,"Name":"NomalEnemy","SpawnCount":160}

変更点は、「Jsonデータを格納するクラス、Dataクラスのプロパティと同じようにJsonの変数名の最初を大文字に変更した」という点。
すると、実行結果が

Hello World!
11
NomalEnemy
160

となった。
というわけで、謎のバグの原因はどうやら「大文字小文字を区別する(=jsonの変数名とプロパティの名前を大文字小文字まで同じにしないといけない)」というルールが原因だったことが判明。

俺の3時間は何だったんだ。

反省

素早く先輩や同級生に質問すべきでした。
意地を張るのは良くない。

余談

ちなみに、NuGetパッケージにある「DynamicJson」では、大文字小文字は区別されないようで、上にあげた修正前のjsonファイルとサンプルコードでも期待通りの出力結果が得られます。
これが混乱を招いた原因の一つです。ちくしょう


  1. うまくいくかは知らない

  2. テキストデータなどのように1つにまとまっているデータから、複数の変数やオブジェクトを取り出すこと。このブログの例で言えば、jsonという1つのテキストデータから、「Id」「Name」「SpawnCount」という複数の値を取り出している。この逆の操作(複数の値やオブジェクトを1つのデータに格納すること)をシリアライズという(らしい)