[C#] 12.1.2 사용자 지정 직렬화

C#에서는 직렬화할 때 메터데이터 부분을 개발자가 정한 이름으로 직렬화할 수 있게 사용자 지정 직렬화를 제공합니다. 사용자 지정 직렬화하려면 ISerializable 인터페이스를 기반으로 정의해야 합니다.

[Serializable]
class Man:ISerializable

그리고 ISerializable에 기능 약속한 GetObjectData 메서드를 정의합니다.

public void GetObjectData(SerializationInfo info, StreamingContext context)
{
 직렬화할 대상을 SerializationInfo 개체의 AddValue 메서드를 이용하여 원하는 이름으로 값을 추가합니다.
    info.AddValue("이름", Name);
    info.AddValue("나이", Age);
}

사용자 지정 직렬화 형식 개체를 역직렬화를 가능하게 하려면 역직렬화에 사용할 생성자를 추가해야 합니다. 역직렬화에 사용할 생성자의 입력 인자는 GetObjectData 메서드와 같습니다.

public Man(SerializationInfo info, StreamingContext context)
{
    //역직렬화하기 위해 SerializationInfo 개체의 GetXXX메서드를 기록한 이름으로 값을 얻어옵니다.
    Name = info.GetString("이름");
    Age = info.GetInt32("나이");
}

다음은 사용자 지정 직렬화 데모 코드입니다.

▶ 직렬화 대상 Man 클래스 정의

using System;
using System.Runtime.Serialization;
namespace 사용자_지정_직렬화
{
    [Serializable]
    class Man:ISerializable
    {
        internal string Name
        {
            get;
            private set;
        }
        internal int Age
        {
            get;
            private set;
        }

        internal Man(string name, int age)
        {
            Name = name;
            Age = age;
        }
        public override string ToString()
        {
            return string.Format("이름:{0} 나이:{1}", Name, Age);
        }
        public Man(SerializationInfo info, StreamingContext context)
        {
            Name = info.GetString("이름");
            Age = info.GetInt32("나이");
        }
        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("이름", Name);
            info.AddValue("나이", Age);
        }
    }
}

▶ 직렬화 사용

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Soap;
namespace 사용자_지정_직렬화
{
    class Program
    {
        static void Main(string[] args)
        {
            Man man = new Man("홍길동", 29); //직렬화 대상 개체
            FileStream fs = new FileStream("man.xml", FileMode.Create); //직렬화 대상 매체
            SoapFormatter sf = new SoapFormatter(); //포멧터
            sf.Serialize(fs, man); //직렬화 수행
            fs.Close();
            FileStream fs2 = new FileStream("man.xml", FileMode.Open);//대상 매체
            SoapFormatter sf2 = new SoapFormatter(); //포멧터
            Man man2 = sf2.Deserialize(fs2) as Man; //역직렬화
            fs2.Close();
            Console.WriteLine(man2);
        }
    }
}