デジタルコンテンツの制作

nekosuko.jp

Unity(C#) ブログ 学習

【Unity】JsonUtilityを使ったときのコンストラクタの検証

更新日:

シリアライズ化したデータを復元してクラスのデータに代入したとき、すなわちnew演算子を書かずにクラスのインスタンス化をしたときそのクラスのコンストラクタがどう動くのか検証しました(もちろんnewを書いてないだけでJsonUtilityとかがインスタンス化してるんだろうと思いますが、その中の動きまでは検証しません)。

メカニズムを知っている人にとっては当たり前のことなのかもしれませんが自分的には知らなかったのでメモ書きしておきます。

まずシリアライズ化したクラスデータを用意する

まず以下のようなクラスを用意します。


public class Unit
{
  public string name;
  public int lv;
  public int hp;

  public Unit()
  {
    Debug.Log("コンストラクタ");
    lv = 5;
  }
}

そしてこのクラスをインスタンス化します。

 
Unit hero = new Unit();

このときもちろんコンストラクタが実行されるのでコンソールに"コンストラクタ"と表示され、lvは5になります(nameはnull、hpは0)。で、さらに内容を書き換えます。

 
hero.name = "NAPA";
hero.lv = 10;
hero.hp = 50;

そしてこのデータをシリアライズ化すると。

{"name":"NAPA","lv":10,"hp":50}

となります。

シリアライズ化したデータを復元する

Unit hero;
string json = "{ \"name\":\"NAPA\",\"lv\":10,\"hp\":50}";
hero = JsonUtility.FromJson<Unit>(json);

Unit型のheroを宣言していますが、インスタンス化はしていません。そこに先ほどシリアライズ化した文字列をJsonUtilityでUnit型のデータに復元してheroに代入します。

Debug.Log(hero.name);
Debug.Log(hero.lv);
Debug.Log(hero.hp);

そして実行して復元されたデータを見てみると。

こんな感じに出力されます。

コンストラクタはJsonUtilityでデータを復元したときに実行されています。ただ、コンストラクタの実行でデータが初期化されていないので、JsonUtilityの中でインスタンス化されたあとに値が代入されているんだろうと思います。

結論として、JsonUtilityでクラスのデータを復元したときコンストラクタは実行される、ということです。

これ以外とやっかいなことがあって、プレイデータなどを復元したときとかにコンストラクタが実行されると、まだインスタンス化されていないクラスとかを参照してしまいかねません(もちろんエラーになる)。まあ、そこはクラス設計が間違っているのかもしれませんが、現状そんな問題を抱えています。

なお、JsonUtilityでクラスのデータを復元したとき引数のあるコンストラクタは実行されません。もし上記の問題をとりあえず解決するならコンストラクタに引数を用意するしかないかなぁ、なんて考えています。

 

-Unity(C#), ブログ, 学習

Copyright© nekosuko.jp , 2020 All Rights Reserved.