クラスのメソッドに自クラスをJSON形式でシリアライズして保存し退避する機能とJSON形式のファイルを読み込みデシリアライズして元のオブジェクトに戻し回復する機能を持たせたい。
プロジェクトの作成
mkdir プロジェクト名
cd プロジェクト名
dotnet new console
ソースコード
using System;
using System.Text;
using System.Text.Json;
using System.IO;
namespace JsonDesili
{
public class Sample
{
public int A { get; set; } = 0;
public string B { get; set; } = "";
public void Save(string path = @".\sample.json")
{
// 自分自身をシリアライズ
var jsonStr = JsonSerializer.Serialize(this);
// エンコードを指定して保存
var encoding = Encoding.GetEncoding("utf-8");
using( var writer = new StreamWriter(path, false, encoding))
{
writer.WriteLine(jsonStr);
}
}
public void Load(string path = @".\sample.json")
{
// エンコードを指定して読み込み
var jsonStr = "";
var encoding = Encoding.GetEncoding("utf-8");
using( var reader = new StreamReader(path, encoding))
{
jsonStr = reader.ReadToEnd();
}
// デシリアライズ
var loadObj = JsonSerializer.Deserialize<Sample>(jsonStr);
// タイプを取得
var type = loadObj.GetType();
// 同じクラスか確認
if (type == this.GetType())
{
// プロパティの一覧を取得
foreach(var i in type.GetProperties())
{
// プロパティを取得
var property = type.GetProperty(i.Name);
// 読み込んだオブジェクトのプロパティの値を取得
var v = property.GetValue(loadObj);
// 自オブジェクトのプロパティに値をセット
property.SetValue(this, v);
}
}
}
}
class Program
{
static void Main(string[] args)
{
// JSonの保存パス
var jsonPath = @".\sample.json";
// オブジェクトの生成
var sample1 = new Sample
{
A = 100,
B = "TEST",
};
// 保存
sample1.Save(jsonPath);
// オブジェクトの生成
var sample2 = new Sample();
// 読み込み
sample2.Load(jsonPath);
// プロパティをコンソールに出力
Console.WriteLine("A:{0} B:{1}", sample2.A, sample2.B);
// 結果 A:100 B:TEST
}
}
}
説明
デシリアライズしたオブジェクトのプロパティを自オブジェクトのプロパティにコピーする部分はリフレクションという機能を使っています。初めて使いましたが結構回りくどいコードになりました。これによりクラスのプロパティが増減してもデシリアライズ部分のコードを変更する必要ない作りになっています。
コメント