いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

.NET クラスライブラリ探訪-028 (シリアライズ-1)(Serializable, XmlSerializer, BinaryFormatter, SoapFormatter)


今回から、数回に分けてシリアライズ系のクラスを取り上げていこうと思います。


.Netではオブジェクトのシリアライズがとても簡単に行えるようになっています。
また、frameworkの全域にわたって利用されています。


今回は、最も基本的なシリアライズ方法についてです。
利用する属性及びクラスは以下の通り。


特定のオブジェクトをシリアライズするには、まず型にシリアライズ可能であることを
示すマークを付与します。.NetではSerializable属性がそれに当たります。

[Serializable]
public class Data1
{
    ....
}


注意点として、シリアライズ可能なのは、publicな型のみとなっています。


後は、実際の処理にてシリアライズします。
例として、XmlSelializerを利用する場合は以下のようになります。

using (TextWriter writer = new StreamWriter("Data1.xml", false, Encoding.GetEncoding("sjis"))
{
    // シリアライズ.
    var serializer = new XmlSerializer(typeof(Data1));
    serializer.Serialize(writer, data);
}


逆にデシリアライズする場合は以下のようにします。

using (TextReader reader = new StreamReader("Data1.xml", Encoding.GetEncoding("sjis")))
{
    // デシリアライズ
    var serializer = new XmlSerializer(typeof(Data1));
    Data1 deserializedObject = (serializer.Deserialize(reader)) as Data1;
}


BinaryFormatterの場合も基本は同じです。こちらは出力される内容がバイナリになります。
SoapFormatterの場合は、Soap形式となります。


以下サンプルです。

using System;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Formatters.Soap;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace SerializationSample
{
    class Program
    {
        static void Main(string[] args)
        {
            //
            // 普通のシリアライズ処理.
            //
            Console.WriteLine("============ (Serialize) ===========");
            
            Data1 data1 = new Data1
                {
                    Id = 1,
                    Name = "Name-1"
                };

            PrintXmlSerializedData(Console.Out, data1);
            WriteXmlSerializedData("Data1.xml", data1);

            //
            // 普通のデシリアライズ処理.
            //
            Console.WriteLine("============ (Deserialize) ===========");
            PrintDeserializedData(typeof(Data1), "Data1.xml");

            Console.WriteLine("Press any key to exit...");
            Console.ReadLine();
        }

        #region Helper Methods
        private static void PrintXmlSerializedData(TextWriter writer, object data)
        {
            if (data == null)
            {
                return;
            }
            
            if (writer == null)
            {
                writer = Console.Out;
            }

            new XmlSerializer(data.GetType()).Serialize(writer, data);
            Console.WriteLine(string.Empty);
        }

        private static void WriteXmlSerializedData(string filePath, object data)
        {
            if (data == null)
            {
                return;
            }

            using (TextWriter writer = new StreamWriter(filePath, false, Encoding.GetEncoding("sjis")))
            {
                (new XmlSerializer(data.GetType())).Serialize(writer, data);
                Console.WriteLine(string.Empty);
            }
        }

        private static void PrintDeserializedData(Type type, string filePath)
        {
            using (XmlReader reader = XmlReader.Create(filePath))
            {
                var data = new XmlSerializer(type).Deserialize(reader);
                foreach (PropertyInfo propInfo in data.GetType().GetProperties())
                {
                    Console.WriteLine("{0}={1}", propInfo.Name, propInfo.GetValue(data, null));
                }
            }
        }
        #endregion
    }

    #region Sample Classes
    //
    // シリアライズ可能な型
    //
    // シリアライズを可能にするには、Serializable属性を付加する.
    // 尚、シリアライズ可能なのはpublicな型のみとなる.
    //
    [Serializable]
    public class Data1
    {
        public int Id
        {
            get;
            set;
        }

        public string Name
        {
            get;
            set;
        }
    }    
}

================================
過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。