0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

C#でオブジェクトのシリアライズ・デシリアライズ(json)

Posted at

概要

C#アプリで設定情報を設定ファイルに書き出し⇔読み出しするためにシリアライズするところで盛大にはまったので、結果を遺しておきます

コード

シリアライザ

    /// <summary>
    /// シリアライズ・デシリアライズをするクラス
    /// </summary>
    /// <typeparam name="T">対象クラス</typeparam>
    class Serializer<T>
    {
        /// <summary>
        /// オブジェクトをUTF-8のjsonファイルにシリアライズする。
        /// </summary>
        /// <param name="obj">対象オブジェクト。要件1=POCOであること。要件2=シリアライズ対象メンバがpublicでgetter/setterがついていること</param>
        /// <param name="filePath">シリアライズ先のファイルパス。既存の場合は上書きされる。</param>
        public static void jsonSerializeUtf8(T obj, string filePath)
        {
            var options = new System.Text.Json.JsonSerializerOptions
            {
                // trueだと出力を整形する
                WriteIndented = true,
                // UNICODEエスケープシーケンスにしない対象を指定。やらないと、ASCII文字以外すべてが あ → \u3042 みたいな感じでエスケープされる。
                Encoder = System.Text.Encodings.Web.JavaScriptEncoder.Create(System.Text.Unicode.UnicodeRanges.All),
            };
            byte[] jsonOutput = System.Text.Json.JsonSerializer.SerializeToUtf8Bytes(obj, options);
            System.IO.File.WriteAllText(filePath, System.Text.Encoding.UTF8.GetString(jsonOutput));
        }

        /// <summary>
        /// シリアライズされたUTF-8のjsonファイルから、オブジェクトを復元する。
        /// </summary>
        /// <param name="filePath">シリアライズされたファイルのパス。</param>
        /// <returns>復元されたオブジェクト</returns>
        public static T jsonDeserializeUtf8(string filePath)
        {
            byte[] jsonInput = System.IO.File.ReadAllBytes(filePath);
            var utf8Reader = new System.Text.Json.Utf8JsonReader(jsonInput);
            return System.Text.Json.JsonSerializer.Deserialize<T>(ref utf8Reader);
        }
    }

usingなしで動くように書いたので若干もっさいです。

手段がjsonであることについて

設定ファイルの選択肢としてはapp.configあたりがあったり、他のシリアライズ手段としてはxmlシリアライズあたりがありますが、
・app.configはkey-value式なので複雑な構造はめんどくさい
・xmlシリアライズはLISTの格納時に色々めんどくさいっぽい
あたりでjsonに絞りました。
実際、コード内の public static void jsonSerializeUtf8 のコメントに書いた通り、POCOかつgetter/setter付きにすれば問題なく動いてくれています。

ポエムな背景

設定ファイルを読み書きしたい
→App.config ・・・xmlで定義しないとだめっぽい?しかもkey-valueだけ?
→xml・・・Listが入るとうまくいかない。サンプルコードによると保存時にコードに特別な処理が必要?やってられん
→json・・・公式の記事からするとこれが最新の手段だから楽になってくれてるかもしれない・・・頼む・・・→いけた :laughing:

0
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?