【C#】Json.NETでインターフェイス型のオブジェクトをデシリアライズする

はいどーもこんにちは、社会人風をブイブイ吹かせたい主夫希望のニートモドキです。
本日はJson.NETを使って、インターフェイス型のオブジェクトをデシリアライズする方法を書いてみたいと思いますよ。
なお、最初の方はJson.NETの簡単な使い方もまとめていますので、ズバリ「インターフェイス型のオブジェクトをデシリアライズする方法」を知りたい方は下の方まで飛ばしてください。

そもそもJson.NETってなんやねん

Json.NETはNewtonsoftさんが公開している、.NETのためのJSONフレームワークらしいです。
要はオブジェクトをJSONにシリアライズしたり、JSONテキストをオブジェクトにデシリアライズしたりするわけですね。
.NET FrameworkにはDataContractJsonSerializerというものがありますし、UnityにはJsonUtilityというものがありますが、たぶんJson.NETの方が直感的で使いやすいです(ただJsonUtilityはめちゃ高速らしいので、ゲームにはこっちのがいいんでしょうね)。
NuGetから入手できますんで、ホイホイDLしといてください。
ちなみにツクラーにおなじみのMITライセンスですよ。

どうやって使うねん

したあと、以下のような感じで使います。

objにはJSONテキストにシリアライズしたいオブジェクトのインスタンスを渡します。
戻り値がJSONテキストですね。

このJSONテキストを元のオブジェクトに戻したい場合、こんな感じです。

わお簡単。

インターフェイスでエラー

僕は現在作成中のツールでObservableCollection<T>型のコレクションをJSONにシリアライズし、保存と読み込みをやろうと思いました。
それはそれで全然問題ないのですが、問題はT型のクラスがインターフェイス型のオブジェクトを保持していたことです。
実際にやってみるとわかると思うのですが、インターフェイス型のオブジェクトをデシリアライズしようとするとエラーが出てしまいます(ようわからんけどシリアライズするときにはエラーが出ない)。

ググってみて

これは困ったということでググってみたところ「JsonConverterのサブクラスを作って、デシリアライズできるようにすればいいよ! HAHAHA!」みたいなクソめんどくさい方法ばかりがヒットしました。
もっと簡単な方法はないのかと思ってさらにググると、以下のサイトに実に簡潔な方法が載っていました。
https://stackoverflow.com/questions/15880574/json-net-how-to-deserialize-collection-of-interface-instances
色々と書かれていますが、注目したいのは「TypeNameHandling.Auto」のことについて触れている方です。
その方によれば、サブクラスをなんやら実装しなくても、単にTypeNameHandling.Autoを設定すればそれでインターフェイス型のインスタンスをデシリアライズできるというのです。

実装してみる

さっそく実装してみましょう。
というわけでコードをドン。

このクラスの使い方はこんな感じ。

これでインターフェイスを含むクラスのインスタンスもちゃんとデシリアライズできるようになりました!
試していませんが、抽象クラスもこれでいけるんじゃないですかね。いけなかったらすみません。

終わりに

わかれば「なんだこんな簡単にできるのか!」って感じなんですが、そこにたどり着くまでが大変なことって多いですよね。
インターフェイス型のオブジェクトをデシリアライズする方法もそれで、意外と詰まりました。
あと日本語の情報がほとんど見当たらなかったので今回は記事として上げてみましたよ。
誰かのお役に立てれば幸いです。

あ、そういや前回のお仕事募集ですが、今の会社で続投することが決まったのでやっぱナシで!
ほなそんな感じでまた。

フォローする