매번 아래와 같은 코드를 직접작성하는 것은 실수를 유발할 수 있다
 자동화를 해보자
class PlayerInfoReq : Packet
{
    public long playerId;
    public string name;
    public struct SkillInfo
    {
        public int id;
        public short level;
        public float duration;
        public bool Write(Span<byte> s, ref ushort count)
        {
            bool success = true;
            success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), id);
            count += sizeof(int);
            success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), level);
            count += sizeof(short);
            success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), duration);
            count += sizeof(float);
            return success;
        }
        public void Read(ReadOnlySpan<byte> s, ref ushort count)
        {
            id = BitConverter.ToInt32(s.Slice(count, s.Length - count));
            count += sizeof(int);
            level = BitConverter.ToInt16(s.Slice(count, s.Length - count));
            count += sizeof(short);
            duration = BitConverter.ToSingle(s.Slice(count, s.Length - count));
            count += sizeof(float);
        }
    }
패킷을 XML을 통해 정의하자
<?xml version="1.0" encoding="utf-8" ?>
<PDL>
  <packet name="PlayerInfoReq">
    <long name="playerId"/>
    <string name="name"/>
    <list name="skill">
      <int name="id"/>
      <short name="level"/>
      <float name="duration"/>
    </list>
  </packet>
</PDL>
XML이 위와 같이 정의되어 있으면 이를 파싱하는 PacketGenerator를 구현해 보자
namespace PacketGenerator
{
    class Program
    {
        static void Main(string[] args)
        {
            XmlReaderSettings settings = new XmlReaderSettings()
            {
                IgnoreComments = true,
                IgnoreWhitespace = true
            };
            // (참고) PDL.xml파일이 exe와 같은 경로에 있어야함.
            using (XmlReader r = XmlReader.Create("PDL.xml", settings))
            {
                // using을 사용할경우 알아서 Dispose(delete)를 호출해 준다
                r.MoveToContent();
                while(r.Read())
                {
                    Console.WriteLine(r.Name + " " + r["name"]);
                }
            }
        }
    }
}
간단하게 이름정도 읽어온다
템플릿에 자동화된 코드가 들어간다(자세한건 코드 참조)