by WebSurfer
14. December 2022 18:06
Newtonsoft.Json のシリアライザなら .NET の多次元配列を JSON 文字列にシリアライズできるという話を書きます。何を今さらと言われそうですが。(汗)

System.Text.Json 名前空間のシリアライザは多次元配列の JSON シリアル化をサポートしていないようで、試してみましたが System.NotSupportedException がスローされ "The type 'System.String[,,]' is not supported." というエラーメッセージが出ます。(ジャグ配列ならサポートしていることは確認しました)
なので、調べもしないで Newtonsoft.Json も同じだと思っていたのですが、Json.NET 4.5 Release 8 – Multidimensional Array Support, Unicode Improvements によると 10 年も前から多次元配列のシリアライズをサポートしているとのことです。
Microsoft のドキュメント「Newtonsoft.Json と System.Text.Json を比較して、System.Text.Json に移行する」にもいろいろ書いてありますが、多次元配列のサポートについては言及してないです。「さまざまな型のサポート ⚠」に含むのでしょうか?
実際にコードを書いて、Newtonsoft.Json が多次元配列とジャグ配列の両方のシリアライズ/デシリアライズをサポートしていることは確認しました。以下に検証に使ったコードを載せておきます。.NET Framework 4.8.1 のコンソールアプリです。
using Newtonsoft.Json;
using System;
namespace ConsoleAppArrayJson
{
internal class Program
{
static void Main(string[] args)
{
// 多次元配列
var mdArray = new string[30, 12, 31];
for (int i = 0; i < 30; i++)
{
for (int j = 0; j < 12; j++)
{
for (int k = 0; k < 31; k++)
{
mdArray[i, j, k] = $"e-{i}-{j}-{k}";
}
}
}
// ジャグ配列
var jArray = new string[30][][];
for (int i = 0; i < 30; i++)
{
jArray[i] = new string[12][];
for (int j = 0; j < 12; j++)
{
jArray[i][j] = new string[31];
for (int k = 0; k < 31; k++)
{
jArray[i][j][k] = $"e-{i}-{j}-{k}";
}
}
}
// 多次元配列を JSON 文字列にシリアライズ
var json1 = JsonConvert.SerializeObject(mdArray);
// ジャグ配列を JSON 文字列にシリアライズ
var json2 = JsonConvert.SerializeObject(jArray);
// json1 == json2 は true になる
Console.WriteLine($"json1 == json2: {json1 == json2}");
// JSON 文字列を多次元配列にデシリアライズ
var array1 = JsonConvert.DeserializeObject<string[,,]>(json1);
Console.WriteLine($"array1[0,1,2]: {array1[0, 1, 2]}");
// JSON 文字列をジャグ配列にデシリアライズ
var array2 = JsonConvert.DeserializeObject<string[][][]>(json2);
Console.WriteLine($"array2[0][1][2]: {array2[0][1][2]}");
}
}
}
上のコードの実行結果は以下のようになります。
