読者です 読者をやめる 読者になる 読者になる

がりらぼ

WindowsRuntimeの応援ブログ

ポリモーフィズム的なオブジェクトをシリアライズする

C# WindowsRuntime

ポリモーフィズム(多様性)とはオブジェクト指向の3大なんたらの最終奥義?もとい重要なことで、オブジェクト自体をいろんなオブジェクトに入れ、一括管理できるとかいうヤツです。

代表的な使い方としては、いろんなクラスを一括管理するためにそれらが継承する一つの親クラスを作っておき、親クラスの型でリストを作成し、リストに追加するときにそれぞれ違う子クラスを入れることで一括管理が可能となっています。

今回は、そのようなポリモーフィズム的なリストをシリアライズする場合、デシリアライズしたときにデータが失われるということの対処法

まず継承される親クラス(TestParentClass)とそれを継承する2つのクラス(TestChildClass1とTestChildClass2)を用意します。
継承するクラスはそれぞれ独自のオブジェクト(Child1ItemとChild2Item)を所有しています。

    public class TestChildClass1:TestParentClass
    {
        public string Child1Item { get; set; }
        public TestChildClass1()
        {

        }
    }
    public class TestChildClass2:TestParentClass
    {
        public string Child2Item { get; set; }
        public TestChildClass2()
        {

        }
    }

    public class TestParentClass
    {
        public string Item { get; set; }
        public TestParentClass()
        {

        }
    }

それらをListで管理。
このとき、リストの型は継承元、その後Addで追加するときに継承先にすることで複数のオブジェクトを一括管理できる。

List<TestParentClass> items = new List<TestParentClass>();
items.Add(new TestChildClass1 { Child1Item="子1",Item="親"});
items.Add(new TestChildClass2 { Child2Item = "子2", Item = "親" });

ではこれらがシリアライズされるときにどうなるか
まずはJson.netでシリアライズ

//Jsonシリアライズ
var json=JsonConvert.SerializeObject(items);           

シリアライズできてた。この時点ではまだ子独自のItemはある。

[{"Child1Item":"子1","Item":"親"},{"Child2Item":"子2","Item":"親"}]

シリアライズして復元してみましょう。

//Jsonデシリアライズ
var obj= JsonConvert.DeserializeObject<List<TestParentClass>>(json);
//この時点で継承先のTestChildClass1固有のChild1Itemが失われている

TestParentClassのオブジェクトとしてデシリアライズするので子独自のChild1Itemはデシリアライズできず、値が失われることになる。

ではどうやってこういうオブジェクトをシリアライズするかというと.NetにはDataContractSerializerという便利なヤツがあり、これを使うとできるんですけど
今日はつかれたのでここまで..明日書きます