妄想プログラマのらくがき帳 : 7月 2014

2014年7月13日日曜日

[.NET]XmlSerializerでシリアライズするクラスって…

publicなコンストラクタを持ってなくてもいいんですね。ずっとpublicな引数無しコンストラクタが必須だと勘違いしてました。
MSDNを確認してみると…

XML シリアル化の概要 - XML シリアル化に関する考慮事項
  • クラスを XmlSerializer でシリアル化するには、そのクラスが既定のコンストラクターを持つ必要があります。
と書いてあり、どこにもpublicでないとダメだなんて書いてないんですよね。
まあ「既定のコンストラクター」っていうと、クラスにコンストラクタが定義されていない時にコンパイラが自動生成するpublicな引数無しコンストラクタを思い浮かべるから、それで勝手にpublicな引数無しコンストラクタが必須だと思い込んでたんでしょうねw

実際にpublicなコンストラクタを持っていないクラスをシリアライズ&デシリアライズしてみました。
using System.IO;
using System.Xml.Serialization;

namespace XmlSerializerSample
{
    public class SerializeTarget
    {
        private SerializeTarget () {}

        public SerializeTarget(int value1, int value2)
        {
            Prop1 = value1;
            Prop2 = value2;
        }

        public int Prop1 { get; set; }
        public int Prop2 { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            SerializeTarget target = new SerializeTarget(100, 200);

            string serialized;
            XmlSerializer xs = new XmlSerializer(typeof(SerializeTarget));
            using (StringWriter sw = new StringWriter())
            {
                xs.Serialize(sw, target);
                serialized = sw.ToString();
            }

            SerializeTarget deserialized;
            using (StringReader sr = new StringReader(serialized))
            {
                deserialized = (SerializeTarget)xs.Deserialize(sr);
            }
        }
    }
}
この通りコンストラクタがprivateでもシリアライズ&デシリアライズできます。